Regexp ... Einstieg sinnvoll?

Hallo,

ich habe mich gerade gefragt, ob es sinnvoll ist, mit regulären Ausdrücken anzufangen.

Kann mir Jemand erklären, welche Vorteile das bringt?

Ich habe den Eindruck, da ist nur die Syntax so weit verkürzt, daß der Code nur schwer lesbar ist, aber sonst das selbe passiert.
Ist das richtig?

Gruß Rainer

ich habe mich gerade gefragt, ob es sinnvoll ist, mit
regulären Ausdrücken anzufangen.

Kann mir Jemand erklären, welche Vorteile das bringt?

Ich habe den Eindruck, da ist nur die Syntax so weit verkürzt,
daß der Code nur schwer lesbar ist, aber sonst das selbe
passiert.

Hallo Rainer,

ich habe keine korpuslinguistische Bedürfnisse :smile:

Quelle: http://www.bubenhofer.com/korpuslinguistik /kurs/index.php?id=regexp.html

In Vb hat man doch nur begrenzte Möglichkeiten einen Text, Inhalt einer Webseite zu filtern.
Man kann *, ?, Like usw. mischen.
Und man braucht Schleifen usw.

Und regexp (früher gabs mal grep was wohl der Vorläufer war)
macht halt aus unseren längeren Schleifenkonstrukten mit IF-Afragen usw. einen Einzeiler.

Nur, um den Einzeiler schreiben zu können muß man regexp nahezu täglich benutzen müssen. Dann lohnt sich m.E. auch die Einarbeitung.

Vielleicht ist es eine gute Idee, sich nur einige wenige regexp-Ausdrücke zu merken, wie z.B. nur Buchstaben, nur Kleinbuchstaben, nur Zahlen, oder gemischt, zu merken und die dann immer zu benutzen.
Denn wenn man das auch nach 2 Wochen noch flüssig lesen kann ist der Vorteil des kürzeren Codes sehr positiv.

Aber, auch in dem viel mehr frequentieren Excel-Forum wo ich noch bin sehe ich regexp äußerst selten. Und die Antworter die REgexp-Anfragen beantworten sind m.E. immer die gleichen Wenigen.
Sie haben sich wohl darauf spezialisiert bzw. benutzen es selbst sehr oft.

Just my two Pfennige.

Gruß
Reinhard

Hallo Reinhard,

Quelle: http://www.bubenhofer.com/korpuslinguistik
/kurs/index.php?id=regexp.html

danke für den Link! Da habe ich ja wieder viel zu lesen.

In Vb hat man doch nur begrenzte Möglichkeiten einen Text,
Inhalt einer Webseite zu filtern.
Man kann *, ?, Like usw. mischen.
Und man braucht Schleifen usw.

hmmm, den Inhalt von Webseiten in eine VB-Variable zu laden schaffe ich schon nicht. :smile:

Und regexp (früher gabs mal grep was wohl der Vorläufer war)

Aha, das ist ja inetressant. Das muss ich mir doch mal genauer ansehen. Danke! Grep tippe ich ständig, ohne zu wissen, was ich da treibe. :smile:

‚ps -efa |grep rainer‘
zeigt mir alle meine Prozesse…
Daß damit noch mehr geht, war mir nicht klar. Ach so, das ist SCO-Unix, kein Windows. :smile:

macht halt aus unseren längeren Schleifenkonstrukten mit
IF-Afragen usw. einen Einzeiler.

Bei AVB habe ich gerade gelesen, daß der reguläre Ausgruck auch schneller sein soll, als die Schleife. Das wäre dann Grund genug. :smile:

Aus dem Beispielcode habe ich mir gerade etwas ‚extrahiert‘, das den Ausdruck zum Laufen bringen soll …

Option Explicit

Private Sub Form\_Load()
 Dim Ret As String, Daten As String
 Daten = "Test"
 Dim reRLE As New RegExp
 reRLE.Pattern = "Der Ausdruck"
 reRLE.Global = True
 Ret = reRLE.Execute(Daten)
 Me.Print Ret
End Sub

Nun fehlt mir nur noch der Ausdruck, der den String ändert um mal zu testen, ob ich das bis hier her richtig verstanden habe, ob ich Global auch weglassen könnte, was es überhaupt bewirkt und soll …

Wenn das bei langen Schleifen einen Geschwindigkeitsvorteil von 60% bringt, reicht mir das als Grund, da mal ein Wochenende lang zu lesen.

Du kannst das ja scheinbar lesen, gib mir doch mal einen ausdruck, der den String manipuliert. Meinetwegen einfach nur ein UCase. :smile:

Gruß Rainer

Hallo!

Und regexp (früher gabs mal grep was wohl der Vorläufer war)

Das ganz sicher nicht. grep ist nur eine von vielen Anwendungen, die reguläre Ausdrücke nutzen.

Nur, um den Einzeiler schreiben zu können muß man regexp
nahezu täglich benutzen müssen. Dann lohnt sich m.E. auch die
Einarbeitung.

Im Gegenteil. regexp ist eine reine Intellektsachte. Es gibt nur zwei Möglichkeiten. Entweder man hat das Prinzip verstanden, wie z.B. die Funktionsweise eine Verkehrsampel, die man auch nach 10 Jahren im Busch nicht vergisst. Oder man hat es nicht verstanden, scheitert mit seinen „gefühlten“ regexps. Dazwischen gibts nichts.

Hinzu kommt auch noch, dass man auch erkennen muss, ob regexps für ein bestimmtes Problem nutzbar sind oder nicht doch ein Parser nötig ist. Beliebigen html-Code auszuwerten, ist z.B. praktisch unmöglich. Eines meiner Lieblingszitate: Some people, when confronted with a problem, think „I know, I’ll use regular expressions.“ Now they have two problems. — Jamie Zawinski in comp.lang.emacs.

Jan

2 Like

Hallo Rainer,

In Vb hat man doch nur begrenzte Möglichkeiten einen Text,
Inhalt einer Webseite zu filtern.
Man kann *, ?, Like usw. mischen.
Und man braucht Schleifen usw.

hmmm, den Inhalt von Webseiten in eine VB-Variable zu laden
schaffe ich schon nicht. :smile:

schau dir mal den nachstehenden Code an. Anstatt innerHTMl, innerText gibts wohl auch outerText bzw. outerHtml, weiß grad nicht auswendig wo da der genaue Unterschied ist, muß man halt austesten.

Vor Jahren hatte ich mir mal Code gebastelt, der hier in w-w-w ein komplettes Brett ausliest. Inklusive Emailadressen usw.
Ob das nach der Unsichtbarkeitsumstellung der Emailadressen noch ginge weiß ich nicht.

Da man natürlich über eine Schleife alle Bretter auslesen könnte, kann man damit natürlich viel machen.

In einem eigenen Browserfenster nur die Beiträge anzeigen lassen die man will, natürlich keine Sternchen anzeigen, unliebsame User rausfiltern, Bewegungsprofile aufgrund der Beiträge eines Users erstellen, sofortige Benachrichtigung bei eingegangenen Antworten u.v.m.

Vielleicht wäre das dann eine klassische Anwendungssache für RegExp!?

Und regexp (früher gabs mal grep was wohl der Vorläufer war)

Kenn mich da nicht aus.

‚ps -efa |grep rainer‘
zeigt mir alle meine Prozesse…

Das lese ich wie regexp, mit viel Zeit und Dauerrecherche im Internet. obwohl, für regexp gibts glaub eine chm oder hlp bei winXP.
Ich weiß den Namen aber nicht.

Wenn das bei langen Schleifen einen Geschwindigkeitsvorteil
von 60% bringt, reicht mir das als Grund, da mal ein
Wochenende lang zu lesen.

Du kannst das ja scheinbar lesen,

Nene, da täuschst du dich gewaltig, ich bräuchte da mindestens auch ein WE dafür :smile:
Den Code schnipsel den ich im anderen Brett zeigte, stammt aus den beiden Prozeduren die ich hier unten drangehängt habe.
Unabhängig von regexp verstehe ich sowieso nicht was der Code machen soll. Mir listet er nur den Emailadresse die im Code steht, sonst nix.
Vielleicht ist er gedacht für zweitemailadressen oder so.
Aber dieses Rätsel hab ich keine Lust zu lösen.

Da teste ich doch viel lieber regexp beim Auslesen von w-w-w-Seiten, macht mehr Spass *gg*

Gruß
Reinhard

Sub Test()
Dim Z
Close
Open "C:\test\htmltext.txt" For Output As #1
Print #1, GetInnerX("http://www.wer-weiss-was.de", "HTML")
Close 1
Z = Shell("notepad.exe C:\test\htmltext.txt", vbMaximizedFocus)
End Sub
'
Function GetInnerX(strURL As String, Optional strWhat As String = "HTML") As String
Dim objIE As Object, objDoc As Object
Dim strMldg As String
GetInnerX = ""
On Error GoTo ErrorHandler 'evtl. Fehler (auch serverseitig) abfangen
Set objIE = CreateObject("InternetExplorer.Application")
objIE.Visible = False
objIE.Navigate strURL
Do While objIE.Busy
Loop
Set objDoc = objIE.Document
Do While objDoc.readyState "complete"
Loop
Select Case UCase(strWhat)
 Case "HTML"
 GetInnerX = objDoc.Body.InnerHTML
 Case Else
 GetInnerX = objDoc.Body.InnerText
End Select
objIE.Quit
Exit Function
ErrorHandler:
If Err.Number 0 Then
 strMldg = "Fehler 0x" & Hex(Str(Err.Number)) & " wurde ausgelöst von " \_
 & Err.Source & Chr(10) & Err.Description
 MsgBox strMldg, vbCritical, "Fehler beim Zugriff auf WWW via InternetExplorer", Err.HelpFile, Err.HelpContext
 Err.Clear
End If
End Function

die Codes für regexp-test:

Sub Beispiel()
Dim strMailFilter() As String
Dim A As Long
Email\_Filter strMailFilter(), "[email protected]"
If IsArray(strMailFilter) Then
 For A = LBound(strMailFilter) To UBound(strMailFilter)
 Debug.Print strMailFilter(A)
 Next A
Else
 MsgBox "nix gefunden!"
End If
End Sub
'
Public Sub Email\_Filter(ByRef sMailFilter() As String, strB As String)
 Dim varTmp() As Variant
 Dim Regex As Object
 Dim m As Object, Treffer As Object
 Dim lngIndex As Long
 Set Regex = CreateObject("Vbscript.regexp")
 With Regex
 .Pattern = "\b(\w[-.\w]\*@\w[-.\w]\*\.[a-zA-Z]{2,6})\b"
 .IgnoreCase = False
 .Global = True
 Set Treffer = .Execute(strB)
 For Each m In Treffer
 ReDim Preserve sMailFilter(lngIndex)
 sMailFilter(lngIndex) = m.Value
 lngIndex = lngIndex + 1
 Next
 End With
 Set Regex = Nothing
End Sub

Hallo Reinhard,

danke für den Code, damit befasse ich mich am Wochenende. Eine Anwendung für ein Spiel weiß ich schon. :smile:

Gruß Rainer

danke für den Code, damit befasse ich mich am Wochenende. Eine
Anwendung für ein Spiel weiß ich schon. :smile:

Hallo Rainer,

die Chm heißt VBSCRIP5.CHM

Gruß
Reinhard

Hi,

die Chm heißt VBSCRIP5.CHM

? Da fehlt doch ein ‚T‘, oder? :smile:

Was regExp angeht … Ich habe jetzt verstanden, was es kann und wozu es da ist. Wenn ich einen schnellen Parser brauche, befasse ich mich eingehend damit, im Moment geht mich das nichts an.

Bis auf die Verwendung in Deinem Code natürlich. :smile: Aber da ist es ja schon fertig. Das muss ich nicht verstehen, wenn es funktioniert.

Gruß Rainer

Hallo Rainer,

da mir RegExp an allen Ecken und Enden begegnen und sie mir vieles viel einfacher gemacht haben, kann ich nur sagen JA der Einstieg ist sinvoll! :wink:
Reicht vom Inhalt von Textfeldern zu verifizieren, nicht der 1. Normalform entsprechenden Datenbankfeldern auszulesen, bis hin zum einfachen bearbeiten von Strings.
Geht zwar meistens auch alles anders, aber nie so kurz und nicht so schnell.

http://www.regular-expressions.info/reference.html
Hat mir vor allem am Anfang (eigentlich bin ich da immernoch) sehr geholfen.

MfG Dominik

Hallo Rainer,

die Chm heißt VBSCRIP5.CHM

? Da fehlt doch ein ‚T‘, oder? :smile:

Nein, ist noch die gute alte 8.3 Namensdeklaration *nachtrauer*

Was regExp angeht … Ich habe jetzt verstanden, was es kann
und wozu es da ist. Wenn ich einen schnellen Parser brauche,
befasse ich mich eingehend damit, …

*hmmh* wenn man mit regexp sehr schnell alle Kombinationen zwischen

ABCDEFGHIJK
ABCDEFGHIKJ
ABCDEFGHJIK
ABCDEFGHJKI

und
KJIHGFECBA

oder ähnliches im Speicher hätte, sofern alles reinpasst, wäre das natürlich sehr schick bei Kombinatorikaufgaben. Das sind immer Zeitfresser ohne Ende.

Aber dazu müßte man ertsmal Regexp besser kennen.
Teufelskreis irgendwie.

Gruß
Reinhard

Hallo,

da mir RegExp an allen Ecken und Enden begegnen und sie mir
vieles viel einfacher gemacht haben, kann ich nur sagen JA der
Einstieg ist sinvoll! :wink:
Reicht vom Inhalt von Textfeldern zu verifizieren, nicht der

  1. Normalform entsprechenden Datenbankfeldern auszulesen, bis
    hin zum einfachen bearbeiten von Strings.
    Geht zwar meistens auch alles anders, aber nie so kurz und
    nicht so schnell.

hmmm, OK. :smile: Gib doch mal ein kurzes ! Beispiel mit VB.
Ich habe versucht, ein möglichst einfaches Beispiel zu basteln, von dem aus ich mich dann vorarbeiten kann, das ist mir nicht gelungen.

Beispiel:
Text: „Dann basteln wir doch mal ein Beispiel“
Eine sinnvolle Anwending wäre doch wohl alle Wörter zu suchen, die ein ‚a‘ enthalten. Richtig?
Wie sieht der Code dazu in VB6.0 aus?
(Ausgabe in eine Listbox oder auf die Form printen … egal.)

http://www.regular-expressions.info/reference.html
Hat mir vor allem am Anfang (eigentlich bin ich da immernoch)
sehr geholfen.

danke! Die Seite hatte ich schon gefunden. Zusammen mit der Hilfe von VB bekomme ich damit die Ausdrücke, die ich brauche, sicher zusammen. Falls nicht, frage ich hier. :smile:

Gruß Rainer

Hallo Reinhard,

die gute alte 8.3 Namensdeklaration *nachtrauer*

die kenne ich nicht, das war vor meiner Zeit. Da habe ich PCs noch als ‚Dosen‘ belächelt. :smile:

Was regExp angeht … Ich habe jetzt verstanden, was es kann
und wozu es da ist. Wenn ich einen schnellen Parser brauche,
befasse ich mich eingehend damit, …

*hmmh* wenn man mit regexp sehr schnell alle Kombinationen
zwischen

ABCDEFGHIJK
ABCDEFGHIKJ
ABCDEFGHJIK
ABCDEFGHJKI

und
KJIHGFECBA

oder ähnliches im Speicher hätte, sofern alles reinpasst, wäre
das natürlich sehr schick bei Kombinatorikaufgaben. Das sind
immer Zeitfresser ohne Ende.

Aber dazu müßte man ertsmal Regexp besser kennen.
Teufelskreis irgendwie.

OK, dann arbeiten wir uns da mal ein. :smile:

Gruß Rainer

die gute alte 8.3 Namensdeklaration *nachtrauer*

die kenne ich nicht, das war vor meiner Zeit. Da habe ich PCs
noch als ‚Dosen‘ belächelt. :smile:

Hallo Rainer,

nix dolles, max. 8 Zeichen als Dateinamen, max. 3 Zeichen als Dateiendung.
Und Sonderzeichen wie Leerzeichen, Punkte u.v.m. waren verboten.
Auch keine ö,ä,ü.

M.E. kann man heutzutage vielzuviel Sonder-) Zeichen in Namen benutzen, die dann irgendein Programm nicht will.
Z.B.
appS=Shell(„abc.exe Umsätze aus 2009-2010.txt“)
kann schon scheitern wenn abc.exe das Leerzeichen als Trennzeichen für Übergabeparameter erkennt oder die Parameter nur bis zum ersten Leerzeichen hinter dem ersten Parameter einliest o.ä.

Das entspricht dann appS=Shell(„abc.exe Umsätze“), was ja nicht gewünscht ist vom User.

Gruß
Reinhard

Hallo Reinhard,

nix dolles, max. 8 Zeichen als Dateinamen, max. 3 Zeichen als
Dateiendung.
Und Sonderzeichen wie Leerzeichen, Punkte u.v.m. waren
verboten.
Auch keine ö,ä,ü.

M.E. kann man heutzutage vielzuviel Sonder-) Zeichen in Namen
benutzen, die dann irgendein Programm nicht will.
Z.B.
appS=Shell(„abc.exe Umsätze aus 2009-2010.txt“)
kann schon scheitern wenn abc.exe das Leerzeichen als
Trennzeichen für Übergabeparameter erkennt oder die Parameter
nur bis zum ersten Leerzeichen hinter dem ersten Parameter
einliest o.ä.

Das entspricht dann appS=Shell(„abc.exe Umsätze“), was ja
nicht gewünscht ist vom User.

*gg* ja, diese Probleme kenne ich. Solche Namen und Pfade vermeide ich auch, wo es nur geht. Ich würde dann ‚Ums_2009_2010.txt‘ schreiben. Das sind zwar immer noch mehr als 8 Zeichen, aber ohne Leerzeichen, ohne Sonderzeichen. :smile:

Gruß Rainer

Hallo!

Beispiel:
Text: „Dann basteln wir doch mal ein Beispiel“
Eine sinnvolle Anwending wäre doch wohl alle Wörter zu suchen, die ein ‚a‘ enthalten. Richtig?

Ja, wäre auf jeden Fall. Frage: Was ist ein Wort? Gehen wir mal nur von Buchstaben aus.

Da ich null Ahnung von VB6 habe, habe ich mal das Beispiel von http://www.regular-expressions.info/vb.html kopiert und angepasst. An deinen Beispieltext habe ich noch ein paar „Extremfälle“ rangehängt. Das Testen von RegExps ist so eine Sache.

Private Sub Form\_Load()

Dim myRegExp As RegExp
Dim myMatches As MatchCollection
Dim myMatch As Match
Set myRegExp = New RegExp
myRegExp.IgnoreCase = True
myRegExp.Global = True
myRegExp.Pattern = "[a-z]\*a[a-z]\*"
Set myMatches = myRegExp.Execute("Dann basteln wir doch mal ein Beispiel. ax a xa aa")
For Each myMatch In myMatches
 MsgBox (myMatch.Value)
Next

End Sub

Was macht „[a-z]*a[a-z]*“? Es sucht eine Folge von Buchstaben in beliebiger Anzahl, auch 0-mal, gefolgt von einem „a“, gefolgt wieder von einer beliebigen Anzahl Buchstaben. „*“ versucht dabei soviel, wie möglich zu erkennen, d.h. „Dann“ wird komplett erkannt, obwohl ja „Da“ reichen würde. „[a-z]*?a[a-z]*?“ dagegen würde bereits nach „Da“ aufhören.

Problem: An Umlauten etc. scheitert das Programm. Habe auf die Schnelle keinen Schalter gefunden, der Unicode ermöglicht oder Ähnliches.

Pädagogisch sinnvolle Erweiterung der Aufgabe:

  • Alle Wörter, die genau ein a enthalten.
  • Alle Wörter, die ein a und/oder ein b enthalten, bei Ausgabe welches von beiden erkannt wurde.

Jan

1 Like

Hallo,

Ja, wäre auf jeden Fall. Frage: Was ist ein Wort? Gehen wir
mal nur von Buchstaben aus.

Ein Bereich in einem Text, der keine Leerzeichen enthält. :smile:

Da ich null Ahnung von VB6 habe, habe ich mal das Beispiel von
http://www.regular-expressions.info/vb.html kopiert und
angepasst. An deinen Beispieltext habe ich noch ein paar
„Extremfälle“ rangehängt. Das Testen von RegExps ist so eine
Sache.

Private Sub Form_Load()

Dim myRegExp As RegExp
Dim myMatches As MatchCollection
Dim myMatch As Match
Set myRegExp = New RegExp
myRegExp.IgnoreCase = True
myRegExp.Global = True
myRegExp.Pattern = „[a-z]*a[a-z]*“
Set myMatches = myRegExp.Execute(„Dann basteln wir doch mal
ein Beispiel. ax a xa aa“)
For Each myMatch In myMatches
MsgBox (myMatch.Value)
Next

End Sub

Wunderbar! Läuft! Darauf kann ich aufbauen. Nur erst mal verstehen …
Eine Frage habe ich schon, warum .Global = True? Den rest glaube ich beim Überfliegen zu verstehen.

Was macht „[a-z]*a[a-z]*“? Es sucht eine Folge von Buchstaben
in beliebiger Anzahl, auch 0-mal, gefolgt von einem „a“,
gefolgt wieder von einer beliebigen Anzahl Buchstaben. „*“
versucht dabei soviel, wie möglich zu erkennen, d.h. „Dann“
wird komplett erkannt, obwohl ja „Da“ reichen würde.
„[a-z]*?a[a-z]*?“ dagegen würde bereits nach „Da“ aufhören.

Problem: An Umlauten etc. scheitert das Programm. Habe auf die
Schnelle keinen Schalter gefunden, der Unicode ermöglicht oder
Ähnliches.

Das sollte hier auch nicht das Problem sein, ich wollte nur das gerüst stehen haben. Einen Code, der ohne Fehlermeldung durchläuft. Mit den ausdrücken selbst muss ich mich nun befassen.

Pädagogisch sinnvolle Erweiterung der Aufgabe:

  • Alle Wörter, die genau ein a enthalten.
  • Alle Wörter, die ein a und/oder ein b enthalten, bei Ausgabe
    welches von beiden erkannt wurde.

OK, das wird dann meine Aufgabe für die Freizeit … Dann muss ich ja nicht den Code posten, der Ausdruck genügt dafür. :smile:

Bis dann.

Gruß Rainer

Hallo,

ich ziehe die Frage:

‚Eine Frage habe ich schon, warum .Global = True?‘

zurück. :smile:
Antwort: Weil sonst nach dem ersten Treffer abgebrochen wird.

Gruß Rainer

Nachtrag:

myRegExp.Pattern = "[a-z]\*a[a-z]\*"

ist zwar ok, aber

myRegExp.Pattern = "[b-z]\*a[a-z]\*"

etwas konsequenter und schneller.

Jan

Hallo,

ich habe mich nun doch schon mal damit befasst.

Um nur genau 1 ‚a‘ zu finden muss ich ‚^1‘ schreiben, steht in der Hilfe. Nur wohin habe ich nicht verstanden. :smile: Ich habe es mal mit Klammern versucht …

a oder b habe ich hin bekommen:
„[b-z]*a[a-z]*|b[a-z]*“

Wie ich dann allerdings "a: " oder "b: " davor setzen kann konnte ich nicht entdecken. Ich sehe nur, wie ich suchen kann. Von einer ausgabe steht da nichts. Die englische Anleitung kann ich nicht richtig lesen, dafür reicht mein Englisch nicht.

Gruß Rainer

Verweis setzen Regexp
Hallo Rainer,

Um nur genau 1 ‚a‘ zu finden muss ich ‚^1‘ schreiben, steht in
der Hilfe. Nur wohin habe ich nicht verstanden. :smile: Ich habe
es mal mit Klammern versucht …

meinst du das:

myRegExp.Pattern = „[a^1]“

Übrigens, ich mußte in Excel2000 (beruht auf VB6.0) diesen Verweis setzen:

Verweis auf Microsoft VBScript Regular Expressions 5.5

In VB5.0 nutzt das aber nicht, da gibts den wohl nicht.

Gruß
Reinhard