nulpen
Goto Top

Werte über Reguläre Ausdrücke ausgeben VB Script

Guten Tag,
ich hab mich an Regulären Ausdrücken und Scripten versucht, komme aber nicht weiter...........

Jeder Beitrag hier hilft mir weiter mich in die Materie einzuarbeiten

Hallo Zusammen,

die Aufgabenstellung wäre folgende : Aus einer XML alle Werte die mit einem REG-Ausdruck übereinstimmen auszugeben.
Ich teste mit dem SystemScripter rum daher der Test zunächst nur über eine Ausgabe und nicht als Export in eine andere Datei.

Er findet die gesuchten Gesamtstrings und zeigt mir die betroffenen Zeilen mit Wscript.Echo auch an.
D.H. die Suche durch die ganze Datei klappt soweit, ich erhalte die richtigen Zeilen.

Jetzt brauche ich aber nur die im regulären Ausdruck mit () gematchten Werte und zwar genau die 4 die ich haben will

Wie ändere ich zunächst den WScript.Echo Befehl um die benötigten Werte auszugeben.


Bisher 123456 VO blablabla 0,00 blablabla 123,00
gebraucht wird (123456) (VO) (0,00) (123,00) Ohne die Klammern, die sollen nur die Treffer "einrahmen"

Const ForReading = 1
Set objFSO = CreateObject("Scripting.FileSystemObject")  
Set objTextFile = objFSO.OpenTextFile _
    ("c:\test\xmltest.xml", ForReading)  
Set Suche = New regexp

Suche.pattern ="([0-9]*)\W*([NOAV]{2}\W)[0-9 A-Za-z]*[0-9.]* [0-9.]* [0-9,.]*[ EUR]*([0-9,.-]*)[. \w]*[0-9]* [0-9\W]{1,3} ([0-9,.]*) ([0-9.,-]*)$"  

Do Until objTextFile.AtEndOfStream
    strNextLine = objTextFile.Readline
    arrServiceList = Split(strNextLine , "</Field>")  
    If  Suche.Test(arrServiceList(i)) Then WScript.Echo "Treffer:" & arrServiceList(i)  
Loop	

Danke fürs helfen, wahrscheinlich ist das obige auch wenns läuft noch zu unsauber geschrieben.

Ich möchte nacher die 4 Werte zeilenweise in eine Textdatei schreiben, da habe ich aus anderen Scripten von euch schon die Tipss bekommen.

Euer XML/TXT-Batch Frak

Ralf

Danke

[Edit Biber] Codeformatierung [/Edit]

Content-Key: 159902

Url: https://administrator.de/contentid/159902

Printed on: April 16, 2024 at 06:04 o'clock

Member: nulpen
nulpen Feb 01, 2011 at 17:25:49 (UTC)
Goto Top
Hallo Forum,

könnte sein das ich es habe, es werden die Werte richtig ausgegeben. SUBMATCHES scheinen wohl die Untertreffer zu sein.

Hier mein geänderter Code (unsauber) aber das Ergebnis ist in der Ausgabe welches ich brauche:

Const ForReading = 1
Set objFSO = CreateObject("Scripting.FileSystemObject")  
Set objTextFile = objFSO.OpenTextFile _
    ("c:\test\xmltest.xml", ForReading)  

Set RegularExpressionObject = New RegExp

With RegularExpressionObject
.Pattern = "([0-9]*)\W*([NOAV]{2}\W)[0-9 A-Za-z]*[0-9.]* [0-9.]* [0-9,.]*[ EUR]*([0-9,.-]*)[. \w]*[0-9]* [0-9\W]{1,3} ([0-9,.]*) ([0-9.,-]*)$"  
.IgnoreCase = False
.Global = True
End With


Do Until objTextFile.AtEndOfStream
	    strNextLine = objTextFile.Readline
    arrServiceList = Split(strNextLine , "</Field>")  
	StringToSearch = arrServiceList(i)
	Set expressionmatch = RegularExpressionObject.Execute(StringToSearch)
	
	If expressionmatch.Count > 0 Then
		For Each expressionmatched In expressionmatch
		WScript.Echo expressionmatched.SubMatches(0) & ";" & expressionmatched.SubMatches(1) & ";" & expressionmatched.SubMatches(2) & ";" & expressionmatched.SubMatches(3) & ";" & expressionmatched.SubMatches(4)  
		Next
		
	Else

	End If

Loop

Set RegularExpressionObject = Nothing

Danke fürs drüberkucken, ich versuche jeden -Tag zu lernen.

Ralf
Member: bastla
bastla Feb 01, 2011 at 20:27:37 (UTC)
Goto Top
Hallo nulpen!

Nur der Ordnung halber:
In Zeile 18 verwendest Du eine Variable i, der kein Wert zugewiesen wurde - daher ist ihr Wert 0, was bedeutet, dass Du von jeder gelesenen Zeile den Teil vor dem ersten vorkommenden"</Field>" verwendest - wenn Du das ohnehin wolltest, solltest Du anstatt des "i" gleich die Null als Index verwenden ...

Die Zeile 21 (und die zugehörige Zeile 28 sowie die überhaupt sinnlose Zeile 26) sind unnötig - die "For Each"-Schleife wird ohnehin nur ausgeführt, wenn es zumindest eine Übereinstimmung ("expressionmatch") gibt.

Grüße
bastla
Member: nulpen
nulpen Feb 13, 2011 at 11:32:22 (UTC)
Goto Top
Hallo Bastla,

läuft super, ich habe ergänzend noch eine Frage:

Wenn ich jetzt verschiedene Werte die ich nicht mit einem REG-Ausdruck-String abfragen kann auslesen möchte, also den Block

With RegularExpressionObject
.Pattern = "([0-9]*)\W*([NOAV]{2}\W)[0-9 A-Za-z]*[0-9.]* [0-9.]* [0-9,.]*[ EUR]*([0-9,.-]*)[. \w]*[0-9]* [0-9\W]{1,3} ([0-9,.]*) ([0-9.,-]*)$"  
.IgnoreCase = False
.Global = True
End With

mehrfach brauche , wie kriege ich das in die Schleife ?


Beispiel: Im Text sind mehrere Blöcke in der Art von

Name: Meier
Strasse: abc
Wert1: 1213456
Wert2: 22222

usw. vorhanden. Manchmal sind die Felder gefüllt und manchmal nicht. Also geht es in einem REGEX-Befehl nicht.

Da die Feldnamen immer vorhanden sind will ich die Werte oder auch "Leer-Ergebnisse" in einem Rutsch auslesen, das kriege ich irgendwie nicht hin.

Set Suche = New regexp
Set Suche1 = New regexp
Set Suche2 = New regexp
Set Suche3 = New regexp

und dann jeweils den Regulären Ausdruck für jede Suche definieren.

Haut mit der Schleife allerdings nicht hin.

Danke für nen Tip, soll nur in das obige Script mit rein.

Ralf
Member: bastla
bastla Feb 13, 2011 at 20:01:34 (UTC)
Goto Top
Hallo nulpen!

Wenn Du mehrmals die selbe Aktion, nur mit unterschiedlichen Parametern, ausführen willst, bietet sich die Verwendung einer "Function" (wenn es genau ein Ergebnis als Rückgabewert geben sollI) oder eines "Sub" (Unterprogramm, keine unmittelbare Rückgabe von Werten) an - ungetestetes Beispiel:
Const ForReading = 1
Set objFSO = CreateObject("Scripting.FileSystemObject")  
Set objTextFile = objFSO.OpenTextFile _
    ("c:\test\xmltest.xml", ForReading) 'Anmerkung: "ForReading" ist default, daher könnte dieser Parameter auch weggelassen werden ...  

Set RegularExpressionObject = New RegExp

With RegularExpressionObject
.IgnoreCase = False
.Global = True
End With


Do Until objTextFile.AtEndOfStream
    strNextLine = objTextFile.Readline
    arrServiceList = Split(strNextLine , "</Field>")  
    
    Search arrServiceList(0), "([0-9]*)\W*([NOAV]{2}\W)[0-9 A-Za-z]*[0-9.]* [0-9.]* [0-9,.]*[ EUR]*([0-9,.-]*)[. \w]*[0-9]* [0-9\W]{1,3} ([0-9,.]*) ([0-9.,-]*)$"  
    Search arrServiceList(0), "other pattern"  
    Search arrServiceList(0), "one more pattern"  
    '...  
Loop

Set RegularExpressionObject = Nothing
'Ende Hauptprogramm  

Sub Search(StringToSearch, Pattern)
RegularExpressionObject.Pattern = Pattern
Set expressionmatch = RegularExpressionObject.Execute(StringToSearch)

For Each expressionmatched In expressionmatch
    WScript.Echo expressionmatched.SubMatches(0) & ";" & expressionmatched.SubMatches(1) & ";" & expressionmatched.SubMatches(2) & ";" & expressionmatched.SubMatches(3) & ";" & expressionmatched.SubMatches(4)  
Next
End Sub
Grüße
bastla
Member: nulpen
nulpen Feb 13, 2011 at 20:54:20 (UTC)
Goto Top
Hallo bastla,

wie komme ich an die submatches der anderen pattern-werte ran ?

Wenn ich z.B die Werte aus einem Fliesstext

12344p4p Name Ralf kjgjkfjgfjgfjdgjld Strasse Gasse 17 sdlfdldlälfä#slälfäsläsfläsfldaä PLZ 12345 lköäkgkfsdksdfkgs dlkflödkföldskökf
Name Peter kflödskfölkfölfkölkdk Strasse Weg 15 kflsdkdölfködlfköldsksdölkdfölPLZ 88888

auslesen möchte, lokalisiere ich mit regulären Ausdrücken die gewünschten Werte (Name/Strasse/PLZ z.B.)

Da der Text zwischen den Werten aber völlig unterschiedlich ist, kann ich hier mit einem Ausdruck und submatches nichts anfangen.

Es gibt diese Textblöcke allerdings mehrfach im Text so daß ich immer für jeden Block die Werte haben muß. (submatches)

Also mehrere Blöcke mit jeweils deren submatches:

Block 1 : Ralf / Gasse 17 / 12345
Block 2 : Peter / Weg 15 / 88888

Hab schon versucht aus der Suchschleife heraus was zu fnden, er zeigt aber nur den letzten Blockwert an.

Schritte

Suche im Text nach den Werten Name Strasse PLZ und schreibe diese in Datei, dann such weiter und schreibe die nächsten 3 Werte die du findest in die Datei.

Irgendwo hängts beim Verständnis.....

Danke
Ralf
Member: bastla
bastla Feb 13, 2011 at 21:36:43 (UTC)
Goto Top
Hallo nulpen!

Die Frage ist natürlich grundsätzlich einmal: Woran ist zu erkennen, ob ein Teilstring noch zu den Nutzdaten gehört, oder schon "Schrott" ist? Wenn das geklärt wäre, ist der Rest einfach:
Name\s(\S*)\s\S*Strasse\s(\S*)\s\S*PLZ ...
Hier würde jeweils an "Leerräumen" (Leerzeichen, Tab, Zeilenende, ...) getrennt - und das ginge in Deinem Beispiel natürlich für "Gasse 17" schon mal schief - daher: ohne gesichertes Suchkriterium kein vernünftiges Suchergebnis ...

Grüße
bastla
Member: nulpen
nulpen Feb 14, 2011 at 07:26:04 (UTC)
Goto Top
Hallo bastla,

genau das ist ja das Problem, daß ich es mit einem String nicht lösen kann.

Zwischen den benötigten Werten kann alles stehen. So wie es aussieht werden es aber Werte sein, so daß man sich auf einen
Parameter "Feldname1 Leerzeichen Wert1 " festlegen könnte.

Ich kriege nur den Schrott zwischendrin nicht sauber weg.

Wenn ich die einzelnen Werte mit "Feldname1 [0-9,.-]*" "Feldname2 [0-9,.-]*" habe wie kriege ich diese dann in ein Ausgabeformat

Wert1;Wert2
Wert1;Wert2
Wert1;Wert2

da ja alle mehrfach vorkommen, aber immer in der richtigen Reihenfolge.

Ich teste heute abend nochmal ein bischen

Danke

Ralf
Member: Biber
Biber Feb 19, 2011 at 12:13:46 (UTC)
Goto Top
Moin nulpen,


Zitat von @nulpen:
Ich teste heute abend nochmal ein bischen
Magst du ein Snickers, falls es etwas länger daueert?
Oder bist du schon in der Lage, einen Zwischenstand zu berichten?

Grüße
Biber
Member: OKIDOKI
OKIDOKI Feb 09, 2013 updated at 15:28:40 (UTC)
Goto Top
Hallo Biber und bastla,

zu euren Ideen hätte ich auch noch eine bezüglich der sauberen Trennung...

Meine Ausgangsdatei sieht so aus:
-rw-r--r-- 1 testftp users 16485 Feb 8 11:00 editor.xlsx
..
..

In der neuen Datei sollen nur die Dateien (ganz rechts) stehen. Merkmal hier wäre immer der Punkt, sie stehen am Ende und haben eine dreistellige Dateiendung.

Bisherige Ausgabe:
1 testftp users 16485 Feb 8 11:00 editor.xlsx

Mein Code bisher (ebenfalls aus dem Forum), der mir leider noch nicht das finale Ergebnis liefert:

Ein = "test.txt"  
Aus = "test_u.txt"  

Set fso = CreateObject("Scripting.FileSystemObject")  
T = fso.OpenTextFile(Ein).ReadAll

Set rE = New RegExp
rE.Global = True
rE.Pattern = " .*"  

Set A = fso.CreateTextFile(Aus)
Set Matches = rE.Execute(T)
For Each Match In Matches
    A.WriteLine Match
Next
A.Close

PS: Irgendwie komme ich nicht mit rE.Pattern zurecht ;-(
Wer kann mir helfen?


Ich habs, ich habs, ich habs ... juhu!!!


rE.Pattern = "\b(\w.\w[-.\w]*\.[a-zA-Z]{2,6})\b"  

Gruß OKIDOKI