Der Aufbau der Zeichenketten war wie folgt:
Suite 100 123-1234 -> 123-1234
Room 4711 333-12345 -> ungültig
Bldg J (910)222-2222 -> 222-2222
Die Lösung ist recht einfach. Im ersten Schritt wird die potentielle Telefonnummer (letzter Block) herausgelöst. Im zweiten Schritt erfolgt die Konvertierung dieses Strings in eine Maske, die im Anschluss direkt mit der gültigen Struktur (NNN-NNNN) verglichen wird.
LOCAL laZKette(3) as String, lcConvertToN as String, lcDelimiters as String, ;
lcNumBlock as String, lcConverted as String
laZKette(1) = [Bldg J (910)222-2222]
laZKette(2) = [Room 4711 333-12345]
laZKette(3) = [Suite 100 123-1234]
lcConvertToN = [0123456789]
lcDelimiters = [ )]
lcValidStruct = [NNN-NNNN]
STORE [] TO lcNumBlock, lcConverted
CLEAR
FOR i = 1 TO ALEN(laZKette,1)
lcNumBlock = GETWORDNUM(laZKette(i),GETWORDCOUNT(laZKette(i),lcDelimiters),lcDelimiters)
lcConverted = CHRTRAN(lcNumBlock,lcConvertToN,REPLICATE([N],LEN(lcConvertToN)))
IF lcConverted == lcValidStruct
? [TelNr.: ] + lcNumblock + [ ist gültig]
ELSE
? [TelNr.: ] + lcNumblock + [ ist ungültig]
ENDIF
ENDFOR
In einigen Fällen kann es jedoch notwendig sein, eine einzelne Zeichenkette mit mehreren Formaten zu Vergleichen, um diejenige Formatversion zu liefern, die dem Zeichenkettenaufbau entspricht. Im folgenden Beispiel vergleichen wir drei gültige Formate mit 10 Werten.
Die in der Schleife eingesetzten CHRTRAN()-Funktionen konvertieren im ersten Schritt alle Buchstaben nach 'C' und im zweiten Schritt alle Zahlen nach 'N'. Diese Reihenfolge wurde gewählt, damit das 'N' nicht nach 'C' gewandelt wird, was bei umgekehrter Reihenfolge der Fall gewesen wäre. Natürlich hätten wir anstelle von 'N' auch die '9' oder das Nummernzeichen '#' zur Maskierung nehmen können. In diesem Fall wäre die Abarbeitungsreihenfolge irrelevant.
LOCAL laZKette(10) as String, laStruct(3) as String ;
lcConvertToN as String. lcConvertToC as String, ;
lcConverted as String, liPos as Integer, lcMessage as String
laZKette( 1) = [3UUFGP7]
laZKette( 2) = [MCK000989]
laZKette( 3) = [0090892LLG]
laZKette( 4) = [9ABCD2]
laZKette( 5) = [JKL230945]
laZKette( 6) = [JKLM00989]
laZKette( 7) = [JJ2000989]
laZKette( 8) = [3U99G7]
laZKette( 9) = [3UUFGP]
laZKette(10) = [7XYZA1]
laStruct(1) = [NCCCCCN]
laStruct(2) = [CCCNNNNNN]
laStruct(3) = [NNNNNNNCCC]
lcConvertToN = [0123456789]
lcConvertToC = [ABCDEFGHIJKLMNOPQRSTUVWXYZ]
STORE [] TO lcConverted, lcMessage
CLEAR
FOR i = 1 TO ALEN(laZKette,1)
lcConverted = CHRTRAN(UPPER(laZKette[i]),lcConvertToC,REPLICATE([C],LEN(lcConvertToC)))
lcConverted = CHRTRAN(UPPER(lcConverted),lcConvertToN,REPLICATE([N],LEN(lcConvertToN)))
liPos = ASCAN(laStruct,lcConverted,1,0,1,1+2+4)
IF liPos > 0
TEXT TO lcMessage NOSHOW TEXTMERGE PRETEXT 1+2
Konto <<PADR(laZKette(i),11,[ ])>> = Struktur <<liPos>> (<<laStruct(liPos)>>)
ENDTEXT
ELSE
TEXT TO lcMessage NOSHOW TEXTMERGE PRETEXT 1+2
Konto <<PADR(laZKette(i),11,[ ])>> - ungültig -
ENDTEXT
ENDIF
?lcMessage
ENDFOR
Eine Erweiterung auf komplexere Konstrukte ist ebenfalls denkbar. So könnten Gross- und Kleinbuchstaben und auch Sonderzeichen in der Konvertierung Berücksichtigung finden.
Ich bin ja nu auch einer, der soweit wie möglich alles in VFP erschlagen möcht, aber für so ne Aufgabe ist nun mal der Einsatz von "Regulären Ausdrücken" die deutlich bessere, flexiblere, weniger aufwändigere Variante.
AntwortenLöschenZur Ansteuerung der RegEx kann man im ersten Versuch die Klasse aus den FFCs verwenden, Suchmuster zur TelefonNummer-Erkennung findet man zuhauf im Internet (zb hier: http://regexlib.com/DisplayPatterns.aspx?cattabindex=6&categoryId=7)
wOOdy
Hi Woody,
AntwortenLöschenReguläre Ausdrücke sind eine feine Sache. Zu meinen Unix-Zeiten habe ich awk und sed diesbezgl. bis zum Exzess genutzt. Damit man mir also nicht nachsagt, das ich als einziges Werkzeug einen Hammer benutze und deswegen jedes Problem als Nagel ansehe hier nun das von Dir angesprochene Äquivalent über _regexp.vcx... ;-)
SET CLASSLIB TO HOME()+ [ffc\_regexp.vcx]
oexp = CREATEOBJECT([_regexp])
oexp.clear
oexp.pattern = "\d{3}-\d{4}$"
* Liefert 1
?oexp.execute("Suite 100 123-1234")
* Liefert 0
?oexp.execute("Room 4711 333-12345")
* Liefert 1
?oexp.execute("Bldg J (910)222-2222")