1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
*(Вопрос)
 В достаточно большом файле имеется строковая переменная (часть почтового адреса),
 которая содержит ошибки такого рода, что некоторые буквы ошибочно заменены цифрами. Например, строка
 '123B SMITH ST' должна быть на самом деле '1238 SMITH ST'. Эти ошибки произошли на этапе сканирования данных.
 
*Чтобы отловить хотя бы часть подобных ошибок, мне бы хотелось иметь формализованный алгоритм,
отлавливающий такие вещи, как "появление букв в последовательности из чисел". Нужно создать логическую
переменную, которая будет отмечать подобные случаи, и я могу себе представить синтаксис, который
берёт куски строки по 3 символа, например, и проверяет, не равен ли средний символ единице, или двойке, 
и т.д. Но это кажется кошмаром. Будут ли высказаны с вашей стороны какие-то соображения?.

*(Ответ) Из дискуссии в SPSSX-L [SPSSX-L@UGA.CC.UGA.EDU] от имени marso@MY-DEJANEWS.COM
Sent: July 23, 1998 10:42 AM
To: SPSSX-L@UGA.CC.UGA.EDU
Subject: Re: Усложнённый поиск в строковой переменной

Майкл,
  Тут нужно просто зафиксировать факт смену буквенного
  символа на числовой в сплошной последовательности символов.
Дэвид

DATA LIST /id 1-2 address 4-25 (a).
BEGIN DATA
01 123B SMITH ST.
02 461 OCEAN BVD.
03 12A PENNSYLVANIA AVE.
04 444 N. MICHIGAN AVE.
05 22B4 BAKER ST.
END DATA.
STRING  #ALPHA (A26) #NUM (A10) #ADDR (A22).
COMPUTE #ALPHA = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".
COMPUTE #NUM = "0123456789" .
COMPUTE #ADDR = UPCASE(ADDRESS).

LOOP #=2 TO LEN(ADDRESS).
COMPUTE #NC = IND(SUB(#ADDR,#,1),#NUM,1) > 0.
COMPUTE #NP = IND(SUB(#ADDR,#-1,1),#NUM,1) > 0.
COMPUTE #SC = IND(SUB(#ADDR,#,1),#ALPHA,1) > 0.
COMPUTE #SP = IND(SUB(#ADDR,#-1,1),#ALPHA,1) > 0.
IF (#NC * #SP + #SC * #NP) BAD=1.
END LOOP.
EXE .


Или можно сделать ещё короче:

DATA LIST /id 1-2 address 4-25 (a).
BEGIN DATA
01 123B SMITH ST.
02 461 OCEAN BVD.
03 12A PENNSYLVANIA AVE.
04 444 N. MICHIGAN AVE.
05 22B4 BAKER ST.
END DATA.
STRING  #ADDR (A22)   .

COMPUTE #ADDR = UPCASE(ADDRESS).
LOOP #=2 TO LEN(ADDRESS).
IF (IND(SUB(#ADDR,#,1),"0123456789",1) > 0)
  * ( IND(SUB(#ADDR,#-1,1),"ABCDEFGHIJKLMNOPQRSTUVWXYZ",1) > 0)
  + (IND(SUB(#ADDR,#,1),"ABCDEFGHIJKLMNOPQRSTUVWXYZ",1)>0 )
  * (IND(SUB(#ADDR,#-1,1),"0123456789",1) > 0) BAD=1.
END LOOP.
LIST .