Regexp ... Einstieg sinnvoll?

Hallo Reinhard,

meinst du das:

myRegExp.Pattern = „[a^1]“

nein, ich habe mit runden Klammern experimentiert.

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

Verweis auf Microsoft VBScript Regular Expressions 5.5

Ja, den habe ich auch gesetzt.

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

Du kannst ja noch die Variante mit dem Objekt verwenden, die Du gepostet hast. Das hat vermutlich den selben effekt, nur daß dann mal wieder die Intellisense nicht mitspielt. Deshalb mag ich das nicht, ich steh nicht gern im dunkeln. :smile:

Gruß Rainer

Hallo!

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

Puh, das kenne ich nicht. Ich habe leider auch nicht die Doku. Kann mir aber nicht vorstellen, dass das zur Lösung führt.

Allerding ist die Lösung der Aufgabe auch nicht ohne. Solche Lehrer habe ich ja geliebt, denen spontan eine Aufgabe einfiel, von der sie selbst nicht wussten, wie sie zu lösen ist. Das Problem ist nicht die Aufgabe sondern eher meine Definition dafür, was ein Wort ist. Die ist etwas unglücklich gewählt.
Die exakte Lösung (schluck):
myRegExp.Pattern = "(^|[^a-z])[b-z]*a[b-z]*(?=([^a-z]|$))"
Eine vertretbare Lösung wäre vielleicht:
myRegExp.Pattern = "\b[b-z]*a[b-z]*\b"
„\b“ erkennt Wortgrenzen, also wo eine Zeichenfolge aus Wortzeichen anfängt und aufhört. Wortzeichen sind aber nicht nur Buchstaben, sondern auch Ziffern und der Unterstrich „_“. Solange in unserm Beispieltext also keine Ziffern und Unterstriche vorkommen, sind die beiden Lösungen indentisch.

es mal mit Klammern versucht …

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

Nein, das funktioniert nicht. Wörter, die kein a haben und das b nicht an erster Stelle, werden nicht erkannt bzw. nur ein Teil. Von „geben“ wird nur „ben“ erkannt.

Die Lösung ist eigentlich dem Ursprungs-Regexp sehr ähnlich.
myRegExp.Pattern = "[a-z]*[ab][a-z]*"
Der geforderte Buchstabe ist nicht mehr das a, sondern ein Zeichen aus der Zeichenmenge [ab].

Den zweiten Teil der Aufgabe, dass der erkannte Buchstabe ermittelt und angezeigt werden soll, löst man mit den runden Klammern um das, was man ermitteln will. Ich habe mal auch um den Teil davor und dahinter runde Klammern gemacht.

...
myRegExp.Pattern = "([a-z]\*)([ab])([a-z]\*)"
'myRegExp.Pattern = "([a-z]\*?)([ab])([a-z]\*)"

...
 MsgBox ("geforderter Buchstabe: " & myMatch.SubMatches(1) & Chr(13) & \_
 "Teil vorm Buchstaben: " & myMatch.SubMatches(0) & Chr(13) & \_
 "Teil hinterm Buchstaben: " & myMatch.SubMatches(2))
...

Die auskommentierte Variante des Regexps erkennt exakt die selben Wörter, aber einen anderen Buchstaben, wenn nicht nur ein Buchstabe aus der Zeichenmenge [ab] vorkommt.

Jan

1 Like

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 …

Davon ausgehend, dass Reguläre Ausdrücke in allen Programmiersprachen die selbe Syntax haben, hat das ^ - Zeichen je nach Kontext eine von 2 Bedeutungen:

  1. Am Anfang eines Regulären Ausdrucks z.B.
    /^[a-z]+/i
    Sucht nach nicht leeren Zeilen. Das ^ bedeutet Zeilenanfang ($ am Ende bedeutet Zeilenende und /i bedeutet „ignore case“: unterscheidet keine Groß- und Kleinschreibung)
  2. Am Anfang in einer eckigen Klammer:
    /[^a]+/i
    Sucht Text der kein „a“ enthält. Das ^ bedeutet also „NICHT“.

Wenn man sich bestimmte Funde merken will, benötigt man runde Klammern.
Für jede runde Klammer wird eine Rückreferenz auf Funde angelegt die ihr entsprechen
und zwar in der Reihenfolge in der die runden Klammern geöffnet werden.
z.B.
/\b(dar\w*)\b/i
merkt sich alle Vorkommen von Wörtern die mir „Dar“ anfangen.
(\w steht für Wortzeichen also Buchstaben, Umlaute, Zahlen,…)
Einen Bezug auf die erste Klammer kann man mit \1 herstellen auf die zweite mit \2 und so weiter. \0 steht immer für den gesamten Ausdruck.
So kann man z.B. Wiederholungen finden:
/\b(\w+)\1\b/
Findet z.B. „BonBon“, „blabla“ und „huhu“.
Wie man diese Funde dann aber abfragt oder ersetzt ist von der API abhängig die man benutzt
und da ich nicht viel mit Basic zu tun habe, kann ich dazu nichts genaueres Sagen.

Gruß
VoidZer0

OT @ Rainer
Hallo Rainer,

ich glaube nach einem WE können wir einigermaßen flüssig lesen was Jay da so schreibt.
Um selbst komplizierte Dinge so zu codieren, oha, ich sehe da einige WEs :smile:

Gruß
Reinhard

Ach ja… der Mann dessen Betreffstext in 50% aller Fälle mit „OT …“ beginnt :wink:

zu finden mit:
/^OT.*/
:smiley:

Ich weiß, dass Reguläre Ausdrücke für Normal-Sterbliche extrem kryptisch aussehen.
Aber das liegt nur daran, dass sie die Formulierung komplexer Bedingungen
in einer wirklich sehr kompakten Syntax ermöglichen.
„Ein kurzer RegExp sagt mehr als tausend Worte“ :wink:
Man gewöhnt sich aber nach einigen Beispielen recht schnell an die Schreibweise und hat dann ein
sehr mächtiges Werkzeug um komplizierte Textanalysen schnell und einfach durchzuführen.

Einstieg absolut empfehlenswert!

Gruß
VoidZer0

Hallo Jan,

Die exakte Lösung (schluck):
myRegExp.Pattern =
"(^|[^a-z])[b-z]*a[b-z]*(?=([^a-z]|$))"

*gg* so viel zum Thema Lesbarkeit. :smile:
Sollte ich so etwas jemals schreiben können, kann ich das am nächsten Tag schon nicht mehr lesen.

Eine vertretbare Lösung wäre vielleicht:
myRegExp.Pattern = "\b[b-z]*a[b-z]*\b"

Das ist schon etwas kürzer, ich will mal versuchen, das zu verstehen.

„\b“ erkennt Wortgrenzen, also wo eine Zeichenfolge aus
Wortzeichen anfängt und aufhört. Wortzeichen sind aber nicht
nur Buchstaben, sondern auch Ziffern und der Unterstrich „_“.

Eben alles außer Leerzeichen. Das, was ich bekomme, wenn ich mit …
Array = Slpit(Text,Chr(32))
… in VB einen String in einzelne Wörter zerlege.

Der erste Beispiel hat doch aber auch die einzelnen Wörter erkannt, ohne „\b“, einfach nur, weil Du nur nach Zeichen von „a“ bis „z“ hast suchen lassen.

Solange in unserm Beispieltext also keine Ziffern und
Unterstriche vorkommen, sind die beiden Lösungen indentisch.

es mal mit Klammern versucht …

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

Nein, das funktioniert nicht.

OK, ich habe mit dem falschen String getestet. :smile:

Wörter, die kein a haben und das
b nicht an erster Stelle, werden nicht erkannt bzw. nur ein
Teil. Von „geben“ wird nur „ben“ erkannt.

Stimmt. :frowning:

Die Lösung ist eigentlich dem Ursprungs-Regexp sehr ähnlich.
myRegExp.Pattern = "[a-z]*[ab][a-z]*"
Der geforderte Buchstabe ist nicht mehr das a, sondern ein
Zeichen aus der Zeichenmenge [ab].

Aha. Und wenn ich nun nach der Zeichenfolge ‚ab‘ suchen will … Mal sehen ob ich das finde. :smile:

Den zweiten Teil der Aufgabe, dass der erkannte Buchstabe
ermittelt und angezeigt werden soll, löst man mit den runden
Klammern um das, was man ermitteln will. Ich habe mal auch um
den Teil davor und dahinter runde Klammern gemacht.


myRegExp.Pattern = „([a-z]*)([ab])([a-z]*)“
'myRegExp.Pattern = „([a-z]*?)([ab])([a-z]*)“


MsgBox ("geforderter Buchstabe: " & myMatch.SubMatches(1) &
Chr(13) & _
"Teil vorm Buchstaben: " & myMatch.SubMatches(0) & Chr(13) &
_
"Teil hinterm Buchstaben: " & myMatch.SubMatches(2))

Die auskommentierte Variante des Regexps erkennt exakt die
selben Wörter, aber einen anderen Buchstaben, wenn nicht nur
ein Buchstabe aus der Zeichenmenge [ab] vorkommt.

Ahhh, mit den Runden Klammern bekomme ich die Submatches …
Da tauchen schon wieder die nächsten Probleme auf, die ich aber selbst lösen kann. :smile:

Danke für die Erklärung!

Gruß Rainer

Hallo,

Davon ausgehend, dass Reguläre Ausdrücke in allen
Programmiersprachen die selbe Syntax haben, hat das ^ -
Zeichen je nach Kontext eine von 2 Bedeutungen:

  1. Am Anfang eines Regulären Ausdrucks z.B.
    /^[a-z]+/i
    Sucht nach nicht leeren Zeilen. Das ^ bedeutet Zeilenanfang ($
    am Ende bedeutet Zeilenende

OK, so weit verstanden, da müsste ich mir nur noch merken. :smile:
In meinem Beispiel wird da aber nichts zurückgegeben.

und /i bedeutet „ignore case“:
unterscheidet keine Groß- und Kleinschreibung)
2. Am Anfang in einer eckigen Klammer:
/[^a]+/i

Aha, im Moment steht das noch außerhalb des Ausdrucks im Code.
Ich habe versucht, das in den Ausdruck einzubauen, ohne Erfolg. Ich verstehe die Klammern und den stern noch nicht.

Sucht Text der kein „a“ enthält. Das ^ bedeutet also „NICHT“.

OK

Wenn man sich bestimmte Funde merken will, benötigt man runde
Klammern.
Für jede runde Klammer wird eine Rückreferenz auf Funde
angelegt die ihr entsprechen
und zwar in der Reihenfolge in der die runden Klammern
geöffnet werden.
z.B.
/\b(dar\w*)\b/i
merkt sich alle Vorkommen von Wörtern die mir „Dar“ anfangen.
(\w steht für Wortzeichen also Buchstaben, Umlaute,
Zahlen,…)
Einen Bezug auf die erste Klammer kann man mit \1 herstellen
auf die zweite mit \2 und so weiter. \0 steht immer für den
gesamten Ausdruck.
So kann man z.B. Wiederholungen finden:
/\b(\w+)\1\b/
Findet z.B. „BonBon“, „blabla“ und „huhu“.
Wie man diese Funde dann aber abfragt oder ersetzt ist von der
API abhängig die man benutzt
und da ich nicht viel mit Basic zu tun habe, kann ich dazu
nichts genaueres Sagen.

OK, da muss ich noch ein wenig im Nebel stochern.

Immer wenn ich mir einbilde, etwas ansatzweise verstanden zu haben und versuche an dem Ausdruck etwas zu ändern, klappt gar nichts mehr.

Gruß Rainer

Hallo Reinhard,

ich glaube nach einem WE können wir einigermaßen flüssig lesen
was Jay da so schreibt.

ich fürchte, so schnell bin ich nicht. :smile:
Ich glaube ! (nicht wissen) daß [a] bedeutet: suche nach einem Element der Menge der Zeichen innerhalb der eckigen Klammer.
Bereiche kann man mit Minus [c-h] angeben.
Den Stern habe ich nicht verstanden.
Suche etwas, das kein ‚e‘ enthält: [^e] ist auch klar.

Wenn ich jetzt aber alle Wörter will, die entweder ein a oder ein b enthalten, aber kein e, dann hört es schon wieder auf, die Syntax erschließt sich mir nicht.

Um selbst komplizierte Dinge so zu codieren, oha, ich sehe da
einige WEs :smile:

Wenn man das verstanden hat, ist es sicher gar nicht so schwer, nur die Gedankengänge dahinter sind sehr komplex. Damit effektiv und kurz ein Problem zu lösen, ist etwa wie rekursive Programierung. :smile: Die Syntax ist simpel, aber wenn man versucht den Ablauf im Kopf nachzubilden, hebt sich die Schädeldecke. *gg*

Bis jetzt habe ich aber noch nicht einmal die Syntax auch nur ansatzweise verstanden.

Gruß Rainer

Hallo Rainer,

mir fiel eben auf, diesen Linguistik-Link hat w-w-w abgeschnitten.

Hier ist er komplett, vorne die Leerzeichen kannste du ja inzwischen mit regexp rauswerfen :smile:

h t t p://w w w.bubenhofer.com/korpuslinguistik/kurs/index.php?id=regexp.html

Gruß
Reinhard

Hallo Reinhard,

h t t p://w w
w.bubenhofer.com/korpuslinguistik/kurs/index.php?id=regexp.html

OK, damit ist der Stern klar. :smile:

Hast Du auch schon experimentiert?
Wie kann ich alle Wörter ausgeben, die ein a enthalten und kein e

-)

Die erste kleine selbst ausgedachte schwierigkeit und ich finde in der Hilfe keinen Hinweis, den ich verstehe, der da hilft. :frowning:

Gruß Rainer

Hallo!

Wie kann ich alle Wörter ausgeben, die ein a enthalten
und kein e

Schnellschuss: [a-df-z]*a[a-df-z]*

Jan

Hallo!

Eben alles außer Leerzeichen. Das, was ich bekomme, wenn ich
mit …
Array = Slpit(Text,Chr(32))
… in VB einen String in einzelne Wörter zerlege.

Gut, wenn das deine Definition ist (wobei ich Leerzeichen, um Tabulator u.Ä. erweitere), dann ist manches (nicht alles) einfacher.
„Wort“ mit a: \S*a\S* (^|\s)[^a\s]*a[^a\s]*(?=(\s|$))

Der erste Beispiel hat doch aber auch die einzelnen Wörter
erkannt, ohne „\b“, einfach nur, weil Du nur nach Zeichen von
„a“ bis „z“ hast suchen lassen.

Da aber nur exakt ein „a“ gefordert war, würde er einen Teil des Wortes finden. Bei „Alabama“ würde er „Al“ erkennen und zufrieden sein. Wir wären es aber nicht, da wir ja komplette Wörter wollen. Und mit dem Wortbegrenzer \b zwingen wir den regexp dazu, nur ganze Wörter zu akzeptieren. Aber bei deiner Definition - alles zw. Leerzeichen ist „Wort“ - ist \b nicht zu gebrauchen. Da sind die Wortbegrenzer dann \s oder Textanfang (^) oder Textende ($). Das macht das da oben etwas unschön.

Alle regexps oben ungetestet.

Jan

1 Like

Hallo auch hier!

/[^a]+/i

Aha, im Moment steht das noch außerhalb des Ausdrucks im Code.
Ich habe versucht, das in den Ausdruck einzubauen, ohne
Erfolg.

Das ist auch die Schreibweise, wie sie in manchen anderen Sprachen und Anwendungen üblich ist (z.B. PHP, Perl, vi). Das ist sehr uneinheitlich (und hier jetzt eher verwirrend, als hilfreich).
Das da oben wäre bei VB [^a]+ plus myRegExp.IgnoreCase = True , bei Python z.B. [^a]+(?i).

Jan

1 Like

Hallo!

Wie kann ich alle Wörter ausgeben, die ein a enthalten
und kein e

Schnellschuss: [a-df-z]*a[a-df-z]*

Wenn wenn ein „Wort“ etwas ist mit Leerzeichen drumherum:
[^e\s]*a[^e\s]*

Jan

Hallo Jan,

Wie kann ich alle Wörter ausgeben, die ein a enthalten
und kein e

Schnellschuss: [a-df-z]*a[a-df-z]*

Wenn wenn ein „Wort“ etwas ist mit Leerzeichen drumherum:
[^e\s]*a[^e\s]*

danke!

Mit beiden Ausdrücken das selbe Ergebnis, mit beiden Varianten werden die Wörter nicht komplett ausgegeben, sondern nur bis zum ‚a‘.

Mein versuch hatte so ausgesehen:

[a-df-z]*[a][a-df-z]*

Da passiert aber auch nichts anderes.

Gruß Rainer

Hi Jan,

Das ist auch die Schreibweise, wie sie in manchen anderen
Sprachen und Anwendungen üblich ist (z.B. PHP, Perl, vi). Das
ist sehr uneinheitlich (und hier jetzt eher verwirrend, als
hilfreich).
Das da oben wäre bei VB [^a]+ plus
myRegExp.IgnoreCase = True , bei Python z.B.
[^a]+(?i).

OK, die Syntax für VB soll mir reichen, wenigstens ‚myRegExp.IgnoreCase = True‘ kann ich ohne Hilfe lesen. :smile: Mit PHP, Perl und Python werde ich mich vermutlich nie befassen.

vi … kenne ich als unhandlichen Texteditor auf Unix.

Gruß Rainer

Hallo,

Eben alles außer Leerzeichen. Das, was ich bekomme, wenn ich
mit …
Array = Slpit(Text,Chr(32))
… in VB einen String in einzelne Wörter zerlege.

Gut, wenn das deine Definition ist (wobei ich Leerzeichen, um
Tabulator u.Ä. erweitere), dann ist manches (nicht alles)
einfacher.

OK. Wie wäre denn Deine Definition gewesen?Zahlengruppen schleiße ich da dann tatsächlich ein, kein Problem.

„Wort“ mit a: \S*a\S*

Hallo!

Schnellschuss: [a-df-z]*a[a-df-z]*

Wenn wenn ein „Wort“ etwas ist mit Leerzeichen drumherum:
[^e\s]*a[^e\s]*

danke!

Mit beiden Ausdrücken das selbe Ergebnis, mit beiden Varianten
werden die Wörter nicht komplett ausgegeben, sondern nur bis
zum ‚a‘.

Das kann ich nicht nachvollziehen, aber es war wirklich ein Schnellschuss, nämlich wirklich großer Blödsinn. Bei „abcdefg“ z.B. erkennt er natürlich „abcd“ als gültig, denn auch hier weiß der Regexp nicht, dass er nur ganze Wörter erkennen soll. Also muss man auch hier auf Anfang und Ende des Wortes prüfen.

Das sind nicht so die typischen Einsatzbereiche für Regexps.

Jan

1 Like

Hallo Jan,

danke! Ich glaube, ich brauche erst mal ein paar Tage, das alles zu verdauen. :smile:

Gruß Rainer

Das kann ich nicht nachvollziehen, aber es war wirklich ein
Schnellschuss, nämlich wirklich großer Blödsinn.

hallo Jan,

willste Rainer irre machen? Poste bitte nur regexp-Beispiele die du auch getestet hast und die auch funktionieren.
Weil logischerweise, weil du da sehr kompetent bist, glaubt er deinen regexp-Ausdrücken, versucht das nachzubauen und kriegt die Krise weil er denkt bei dir klappen sie und bei ihm nicht :smile:

Schone ihn bitte, wir brauchen ihn noch *gg*

Gruß
Reinhard