[Gelöst] Ist parsen eine regex Aufgabe?

Vom einfachen Programm zum fertigen Debian-Paket, Fragen rund um Programmiersprachen, Scripting und Lizenzierung.
buhtz
Beiträge: 1205
Registriert: 04.12.2015 17:54:49
Kontaktdaten:

[Gelöst] Ist parsen eine regex Aufgabe?

Beitrag von buhtz » 14.03.2022 15:26:37

Um regex konnte ich bisher einen Bogen machen, aber meine aktuelle Aufgabe schein dafür wie gemacht zu sein. Mangels Erfahrung und Schwierigkeiten beim Implementieren bin ich mir da aber unsicher.

Also erstmal die grundsätzliche Frage, ob das mit regex (Python 3.9) machbar ist?

Es geht um Zeilen dieser Art die geparst werden sollen:

Code: Alles auswählen

Lore [[id:0c66c239][foo]]
Lore [[id:0c66c239][foo]] end
Ipsum Lore [[id:0c664422c239][bar]]
Ipsum Lore [[id:0c664422c239][bar]] Lore [[id:0c66c239][foo]]
Als Ergebnis der ersten Zeile möchte 0c66c239 und foo als Wertepaar haben. In der letzten Zeile wären es entsprechend zwei Wertepaare.
Was vor [[id:] oder nach ]] kommt ist unbestimmt. Ebenso variable ist die Anzahl der Wertepaare je Zeile.

Pythons re.findall() scheint dafür gedacht zu sein eine unbestimmte Anzahl von Ergebnissen zurück zuliefern.
Zuletzt geändert von buhtz am 18.04.2022 13:29:14, insgesamt 3-mal geändert.
Debian 11 & 12; Desktop-PC, Headless-NAS, Raspberry Pi 4
Teil des Upstream Betreuer Teams von Back In Time (Debianbackintime)

Benutzeravatar
Meillo
Moderator
Beiträge: 9224
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: Ist parsen eine regex Aufgabe?

Beitrag von Meillo » 14.03.2022 15:38:27

Dabei helfen dir Regexps auf jeden Fall. Es ginge auch ohne -- z.B. mittels Recursive Descent (https://de.wikipedia.org/wiki/Rekursiver_Abstieg) --, aber das ist viel umstaendlicher.

In deinem speziellen Fall koenntest du aber auch einen simplen stringbasierten Ansatz waehlen: Den Input in Worte unterteilen (d.h. split an Whitespace), dann alle Woerter irgnorieren, die nicht mit `[[id:' beginnen. In den relevanten Woertern dann mit Substring-Operationen die gewuenschte Information rausholen. (Regexps erlauben dir das gleiche, nur mit weniger Code.)
Use ed once in a while!

buhtz
Beiträge: 1205
Registriert: 04.12.2015 17:54:49
Kontaktdaten:

Re: Ist parsen eine regex Aufgabe?

Beitrag von buhtz » 14.03.2022 15:47:47

Meillo hat geschrieben: ↑ zum Beitrag ↑
14.03.2022 15:38:27
In deinem speziellen Fall koenntest du aber auch einen simplen stringbasierten Ansatz waehlen:
Das ist ne einfache und gute Idee, die ich auch mal probieren werde.

Mit regex habe ich immer so mein Problem, da es (streng genommen) nicht menschenlesbar und somit wartbar ist. Aber ich hab hier mal einen Ansatz versucht, nachdem ich mir ein paar pattern aus SO abgeschaut habe, ohne zu wissen ob das wirklich sinnvoll oder in jedem Fall korrekt ist.

Das Pattern für eine ID lautet \[\[id:(.+)\]\[(.+)\]\]. Vorab zähle ich im String wie viele IDs vorkommen und vervielfältige das Pattern entsprechend.

Code: Alles auswählen

#!/usr/bin/env python3
import re

# lines to search in
lines = [
    'Lore [[id:0c66c239][foo]]',
    'Lore [[id:0c66c239][foo]] end',
    'Ipsum Lore [[id:0c664422c239][bar]]',
    'Ipsum Lore [[id:0c664422c239][bar]] Lore [[id:0c66c239][foo]]'
]

# search patter for one occurence of [[id:X][Y]]
REGEX_PATTERN = '\[\[id:(.+)\]\[(.+)\]\]'

# each line
for l in lines:
    # count occurence of id's
    id_count = l.count('[[id:')

    # create regex pattern taking the number of id's to parse into account
    rpattern = '(.*)'.join([REGEX_PATTERN] * id_count)

    # parse
    result = re.findall(rpattern, l)

    # report
    print(f'Parsed content: {l}\nUsed pattern: {rpattern}\n'
          f'Parsed result: {result}\n')
Und der output

Code: Alles auswählen

Parsed content: Lore [[id:0c66c239][foo]]
Used pattern: \[\[id:(.+)\]\[(.+)\]\]
Parsed result: [('0c66c239', 'foo')]

Parsed content: Lore [[id:0c66c239][foo]] end
Used pattern: \[\[id:(.+)\]\[(.+)\]\]
Parsed result: [('0c66c239', 'foo')]

Parsed content: Ipsum Lore [[id:0c664422c239][bar]]
Used pattern: \[\[id:(.+)\]\[(.+)\]\]
Parsed result: [('0c664422c239', 'bar')]

Parsed content: Ipsum Lore [[id:0c664422c239][bar]] Lore [[id:0c66c239][foo]]
Used pattern: \[\[id:(.+)\]\[(.+)\]\](.*)\[\[id:(.+)\]\[(.+)\]\]
Parsed result: [('0c664422c239', 'bar', ' Lore ', '0c66c239', 'foo')]

Debian 11 & 12; Desktop-PC, Headless-NAS, Raspberry Pi 4
Teil des Upstream Betreuer Teams von Back In Time (Debianbackintime)

Benutzeravatar
Meillo
Moderator
Beiträge: 9224
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: Ist parsen eine regex Aufgabe?

Beitrag von Meillo » 14.03.2022 15:51:24

(Von Python habe ich keine Ahnung.)

Das Pattern sieht auf den ersten Blick gut aus. Das Vervielfaeltigen wird aber unnoetig sein, denn findall() sollte eben gerade in der Lage sein, ein mehrfach vorkommendes Pattern zu matchen und die Treffer dann in einen Array zurueckzuliefern. Lese dich diesbezueglich noch mehr ein. Ich bin mir sicher, dass das Vervielfaeltigen unnoetig ist.
Use ed once in a while!

buhtz
Beiträge: 1205
Registriert: 04.12.2015 17:54:49
Kontaktdaten:

Re: Ist parsen eine regex Aufgabe?

Beitrag von buhtz » 14.03.2022 15:55:38

Meillo hat geschrieben: ↑ zum Beitrag ↑
14.03.2022 15:51:24
Das Vervielfaeltigen wird aber unnoetig sein, denn findall() sollte eben gerade in der Lage sein, ein mehrfach vorkommendes Pattern zu matchen
Vermutlich muss man da was am pattern schrauben. Ohne Vervielfältigung ist das Resultat der letzten Zeile [('0c664422c239][bar]] Lore [[id:0c66c239', 'foo')].
Debian 11 & 12; Desktop-PC, Headless-NAS, Raspberry Pi 4
Teil des Upstream Betreuer Teams von Back In Time (Debianbackintime)

Benutzeravatar
Meillo
Moderator
Beiträge: 9224
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: Ist parsen eine regex Aufgabe?

Beitrag von Meillo » 14.03.2022 16:04:17

buhtz hat geschrieben: ↑ zum Beitrag ↑
14.03.2022 15:55:38
Meillo hat geschrieben: ↑ zum Beitrag ↑
14.03.2022 15:51:24
Das Vervielfaeltigen wird aber unnoetig sein, denn findall() sollte eben gerade in der Lage sein, ein mehrfach vorkommendes Pattern zu matchen
Vermutlich muss man da was am pattern schrauben. Ohne Vervielfältigung ist das Resultat der letzten Zeile [('0c664422c239][bar]] Lore [[id:0c66c239', 'foo')].
Stimmt! ;-)

Versuche mal hinter die zwei Plus-Zeichen ja ein Fragezeichen zu setzen (um den Plus-Quantor ungreedy zu machen). Wenn Python Regexps PCREs sind, dann sollte das gehen.

Alternativ koenntest du den Punkt vor dem Plus (der fuer ein beliebiges Zeichen steht) durch [^]] ersetzen (was fuer ein beliebiges Zeichen ausser einer schliessenden eckigen Klammer steht).
Use ed once in a while!

buhtz
Beiträge: 1205
Registriert: 04.12.2015 17:54:49
Kontaktdaten:

Re: Ist parsen eine regex Aufgabe?

Beitrag von buhtz » 14.03.2022 16:12:47

Vielen Dank für die Hilfe. So hab ich es jetzt mal gemacht. Geht auch. Mehr code, aber den versteh ich auch in einem Jahr noch. ;)

EDIT: Der Code hat einen Bug. Wenn der Linkname ("foo" oder "bar") ein Leerzeichen beinhalten, geht es nicht.

Code: Alles auswählen

#!/usr/bin/env python3
import re

# lines to search in
lines = [
    'Lore [[id:0c66c239][foo]]',
    'Lore [[id:0c66c239][foo]] end',
    'Ipsum Lore [[id:0c664422c239][bar]]',
    'Ipsum Lore [[id:0c664422c239][bar]] Lore [[id:0c66c239][foo]]'
]

for l in lines:
    # split by ' ' and keep id's only
    id_name_pairs = [e for e in l.split(' ') if e.startswith('[[id:')]

    # split id and its name by ']['
    id_name_pairs = [p.split('][') for p in id_name_pairs[:]]

    # beautify
    for idx in range(len(id_name_pairs)):
        # ID: cut beginning '[[id:'
        id_name_pairs[idx][0] = id_name_pairs[idx][0][5:]
        # NAME: cut ending ']]'
        id_name_pairs[idx][1] = id_name_pairs[idx][1][:-2]

    # report
    for i, n in id_name_pairs:
        print(f'{i}:{n}')
Zuletzt geändert von buhtz am 14.03.2022 22:13:13, insgesamt 1-mal geändert.
Debian 11 & 12; Desktop-PC, Headless-NAS, Raspberry Pi 4
Teil des Upstream Betreuer Teams von Back In Time (Debianbackintime)

Benutzeravatar
Meillo
Moderator
Beiträge: 9224
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: Ist parsen eine regex Aufgabe?

Beitrag von Meillo » 14.03.2022 16:54:00

buhtz hat geschrieben: ↑ zum Beitrag ↑
14.03.2022 16:12:47
Vielen Dank für die Hilfe. So hab ich es jetzt mal gemacht. Geht auch. Mehr code, aber den versteh ich auch in einem Jahr noch. ;)
Das ist natuerlich ein Argument. ;-)

Hier dennoch noch der Code mir REs:

Code: Alles auswählen

#!/usr/bin/env python3
import re

# lines to search in
lines = [
    'Lore [[id:0c66c239][foo]]',
    'Lore [[id:0c66c239][foo]] end',
    'Ipsum Lore [[id:0c664422c239][bar]]',
    'Ipsum Lore [[id:0c664422c239][bar]] Lore [[id:0c66c239][foo]]'
]

# search patter for one occurence of [[id:X][Y]]

# each line
for l in lines:
    # pattern
    rpattern = '\[\[id:(.+?)\]\[(.+?)\]\]'

    # parse
    result = re.findall(rpattern, l)

    # report
    print(f'Parsed content: {l}\nUsed pattern: {rpattern}\n'
          f'Parsed result: {result}\n')

Ich kann dir uebrigens nur empfehlen, dich ein bisschen mit REs zu befassen. Sie sind nicht so kompliziert wie sie erscheinen, wenn man sich nur ein bisschen Zeit nimmt, sie kennenzulernen. Dann erleichtern sich einem das Leben bei der Textverarbeitung deutlich.


Wir koennen das gerne als ``Lerndialog'' in Form eines Threads im Forum machen. Dass ich einen Kurs ausarbeite waere zu viel, aber wenn du dich anhand eines RE-Workshops oder einer RE-Einstiegsseite voran hangelst und dabei von deinen Uebungen berichtest und deine Frage stellst, dann stehen dir ich und sicher auch andere gerne zur Seite. Du brauchst nur Zeit und Motivation. ;-)

@TRex, @eggy, @JTH & Co.: Irgendwie waer's schon lustig, eine ``Das DFDE lernt Regulaere Ausdruecke''-Aktion ... vielleicht so aehnlich wie der Alias-Adventskalender damals ... Lasst uns dazu doch mal ein bisschen brainstormen ...
Use ed once in a while!

thoerb
Beiträge: 1685
Registriert: 01.08.2012 15:34:53
Lizenz eigener Beiträge: MIT Lizenz

Re: Ist parsen eine regex Aufgabe?

Beitrag von thoerb » 14.03.2022 18:47:10

Meillo hat geschrieben: ↑ zum Beitrag ↑
14.03.2022 16:54:00

Ich kann dir uebrigens nur empfehlen, dich ein bisschen mit REs zu befassen. Sie sind nicht so kompliziert wie sie erscheinen, wenn man sich nur ein bisschen Zeit nimmt, sie kennenzulernen. Dann erleichtern sich einem das Leben bei der Textverarbeitung deutlich.
Kleiner Tipp am Rande, ich persönlich nutze gerne die Webseite: https://regex101.com/. Da man hier sofort die Auswirkung jeder Änderung sieht und somit schneller zum Ziel kommt.

Benutzeravatar
TRex
Moderator
Beiträge: 8316
Registriert: 23.11.2006 12:23:54
Wohnort: KA

Re: [Gelöst] Ist parsen eine regex Aufgabe?

Beitrag von TRex » 14.03.2022 19:54:43

Meillo hat geschrieben: ↑ zum Beitrag ↑
14.03.2022 16:54:00
@TRex, @eggy, @JTH & Co.: Irgendwie waer's schon lustig, eine ``Das DFDE lernt Regulaere Ausdruecke''-Aktion ... vielleicht so aehnlich wie der Alias-Adventskalender damals ... Lasst uns dazu doch mal ein bisschen brainstormen ...
nice 8)

@meillo: verbessern kannst du das noch in der Performance, indem du den regulären Ausdruck einmal "kompilierst" (das passiert inline, wenn du mit re.findall(Ausdruck, foobar) arbeitest, aber eben in jedem Schleifendurchlauf).

Code: Alles auswählen

rex = re.compile('\[\[id:(.+?)\]\[(.+?)\]\]')
for line in lines:
    rex.findall(line)
Jesus saves. Buddha does incremental backups.
Windows ist doof, Linux funktioniert nichtDon't break debian!Wie man widerspricht

eggy
Beiträge: 3334
Registriert: 10.05.2008 11:23:50

Re: [Gelöst] Ist parsen eine regex Aufgabe?

Beitrag von eggy » 15.03.2022 05:04:08

Offtopic:
@TRex, @eggy, @JTH & Co.: ich habe meine Ideen mal an Meillo per PM geschickt ... ich fänd's schade, wenn wir den anderen vorab durch die Diskussion hier die Überraschung verderben. Ich schlage vor, Meillo kriegt die undankbare Aufgabe, aus den ihm zugesandten Brainstormideen die sinnvollsten Brocken rauszupicken und nen grobes Gerüst für die 24(+x) Tage aufzustellen.
Wer in der Vorbereitung mitmachen will: Kalendergit beim Weinachtsdino? Ich nehm einfach mal an, dass der Dino zumindest soweit mitmacht, dass er das administriert :P

buhtz
Beiträge: 1205
Registriert: 04.12.2015 17:54:49
Kontaktdaten:

Re: [Gelöst] Ist parsen eine regex Aufgabe?

Beitrag von buhtz » 15.03.2022 08:45:17

btw: Ich hab jetzt doch die regex Version genutzt, weil der String-basierte Ansatz nicht funktioniert, wenn der Link-Name ein Leerzeichen enthält. Den Code wollte ich nicht noch weiter mit Sonderbehandlungen aufblähen.
Debian 11 & 12; Desktop-PC, Headless-NAS, Raspberry Pi 4
Teil des Upstream Betreuer Teams von Back In Time (Debianbackintime)

buhtz
Beiträge: 1205
Registriert: 04.12.2015 17:54:49
Kontaktdaten:

Re: [Gelöst] Ist parsen eine regex Aufgabe?

Beitrag von buhtz » 18.03.2022 16:57:12

Noch ein kleines AddOn. Ich muss org-roam-id-links (die mit [[id: beginnen) anders behandeln als alle anderen links.
Jetzt möchte ich zwar solche Links wie [[some-url][link-label]] aber kein org-roam-id-links [[id:2i343][link-label]].

Ich würde also den String "id:" ausschließen wollen; per (?!id\:). So scheint es auf https://regex101.com/ zu klappen. Ist das "sauber"?

Code: Alles auswählen

\[\[(?!id\:)(.+?)\]\[(.+?)\]\]
Bei dieser Lösung sieht man noch ein \b im pattern. Das habe ich nicht verstanden.
Debian 11 & 12; Desktop-PC, Headless-NAS, Raspberry Pi 4
Teil des Upstream Betreuer Teams von Back In Time (Debianbackintime)

Benutzeravatar
Meillo
Moderator
Beiträge: 9224
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: [Gelöst] Ist parsen eine regex Aufgabe?

Beitrag von Meillo » 18.03.2022 17:43:48

buhtz hat geschrieben: ↑ zum Beitrag ↑
18.03.2022 16:57:12
Ich würde also den String "id:" ausschließen wollen; per (?!id\:). So scheint es auf https://regex101.com/ zu klappen. Ist das "sauber"?

Code: Alles auswählen

\[\[(?!id\:)(.+?)\]\[(.+?)\]\]
Das kann man so machen. Es ist jedenfalls nicht falsch und ich schlage auch nicht die Haende ueber den Kopf zusammen (falls du darauf pruefen wolltest ;-) ).

(?!...) ist ein negativer Lookahead in PCRE und bedeutet: Wenn an dieser Stelle kein `id:' folgt (ohne diese Zeichen zu matchen). Man kann das nur nutzen wenn man auch PCREs zur Verfuegung hat, also in den meisten Programmiersprachen aber normalerweise nicht in Unix-Utilities wie grep, sed, awk. (Ja, ich weiss, `grep -P'. :roll: )

buhtz hat geschrieben: ↑ zum Beitrag ↑
18.03.2022 16:57:12
Bei dieser Lösung sieht man noch ein \b im pattern. Das habe ich nicht verstanden.
\b bedeutet Wortgrenze, also auf der einen Seite davon muss ein Wortzeichen [A-Za-z0-9_] sein und auf der anderen ein Nicht-Wortzeichen. In der verlinkten Website will man damit sicherstellen, dass das auszuschliessende Wort nicht als Praefix eines laengeren Wortes auftaucht, sondern fuer sich alleine steht. In deinem Fall ist das auszuschliessende ``Wort'' ja `id:', was durch den Doppelpunkt ja eh begrenzt ist, darum ist das \b hier nicht noetig oder wichtig.
Use ed once in a while!

buhtz
Beiträge: 1205
Registriert: 04.12.2015 17:54:49
Kontaktdaten:

Re: [Gelöst] Ist parsen eine regex Aufgabe?

Beitrag von buhtz » 18.03.2022 20:14:10

Gerade gelernt: In Python (ab welcher Version weiß ich nicht), muss man regex-Pattern mit einem vorgestellen `r` kennenzeichen, sonst spielen die Linter (e.g. pycodestyle) verrückt.
Korrekt(er) ist scheinbar:

Code: Alles auswählen

re.compile(r'\[\[(?!id\:)(.+?)\]\[(.+?)\]\]')
Debian 11 & 12; Desktop-PC, Headless-NAS, Raspberry Pi 4
Teil des Upstream Betreuer Teams von Back In Time (Debianbackintime)

Benutzeravatar
TRex
Moderator
Beiträge: 8316
Registriert: 23.11.2006 12:23:54
Wohnort: KA

Re: [Gelöst] Ist parsen eine regex Aufgabe?

Beitrag von TRex » 18.03.2022 20:24:26

Das sind raw-Strings, und mit regex haben die nichts zu tun - sie sind dafür aber praktisch. Normalerweise müsstest du alle backslashes escapen (also sie zweimal schreiben), und mit raw string (korrekterweise raw string literals) musst du das nicht.

Siehe auch: https://docs.python.org/3/reference/lex ... ml#strings
Both string and bytes literals may optionally be prefixed with a letter 'r' or 'R'; such strings are called raw strings and treat backslashes as literal characters.
Jesus saves. Buddha does incremental backups.
Windows ist doof, Linux funktioniert nichtDon't break debian!Wie man widerspricht

buhtz
Beiträge: 1205
Registriert: 04.12.2015 17:54:49
Kontaktdaten:

Re: [Gelöst] Ist parsen eine regex Aufgabe?

Beitrag von buhtz » 18.03.2022 21:05:03

TRex hat geschrieben: ↑ zum Beitrag ↑
18.03.2022 20:24:26
Das sind raw-Strings, und mit regex haben die nichts zu tun - sie sind dafür aber praktisch. Normalerweise müsstest du alle backslashes escapen (also sie zweimal schreiben), und mit raw string (korrekterweise raw string literals) musst du das nicht.
Das regex Modul in Python scheint das aber nicht zu stören. Bzw. sind die Backslashes ja keine Zeichen, sondern bereits Escape-Einleitungen. Also wenn ich tatsächlich, so wie die Linter das wollen, diese nochmal escapen würde, würde vermutlich regex nicht mehr gehen.
Debian 11 & 12; Desktop-PC, Headless-NAS, Raspberry Pi 4
Teil des Upstream Betreuer Teams von Back In Time (Debianbackintime)

Benutzeravatar
TRex
Moderator
Beiträge: 8316
Registriert: 23.11.2006 12:23:54
Wohnort: KA

Re: [Gelöst] Ist parsen eine regex Aufgabe?

Beitrag von TRex » 18.03.2022 21:20:41

Sorry, war auch ein wenig unvollständig/falsch - escapen musst du einzelne \ nicht, aber würdest du \n (oder \t, \r, ...) im regex verwenden wollen, gehts vermutlich schief ohne wahlweise \\n oder eben r"\n". Habs nicht ausprobiert, aber so interpretiere ich die Doku.
Jesus saves. Buddha does incremental backups.
Windows ist doof, Linux funktioniert nichtDon't break debian!Wie man widerspricht

Benutzeravatar
Meillo
Moderator
Beiträge: 9224
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: [Gelöst] Ist parsen eine regex Aufgabe?

Beitrag von Meillo » 18.03.2022 22:07:55

Bedeutet das, dass in Python r'...' und r"..." das Aequivalent zu Single Quotes in der Shell sind?

Normale '...' und "..." sind dann wohl austauschbar und entsprechen den Double Quotes in der Shell, vermute ich.
Use ed once in a while!

eggy
Beiträge: 3334
Registriert: 10.05.2008 11:23:50

Re: [Gelöst] Ist parsen eine regex Aufgabe?

Beitrag von eggy » 18.03.2022 22:17:18

Meillo hat geschrieben: ↑ zum Beitrag ↑
18.03.2022 22:07:55
Bedeutet das, dass in Python r'...' und r"..." das Aequivalent zu Single Quotes in der Shell sind?

Normale '...' und "..." sind dann wohl austauschbar und entsprechen den Double Quotes in der Shell, vermute ich.
Und """...""" gibts auch noch.

https://peps.python.org/pep-0008/#naming-conventions
pep8 unter String Quotes sagt:
In Python, single-quoted strings and double-quoted strings are the same. This PEP does not make a recommendation for this. Pick a rule and stick to it. When a string contains single or double quote characters, however, use the other one to avoid backslashes in the string. It improves readability.

For triple-quoted strings, always use double quote characters to be consistent with the docstring convention in PEP 257.
und das sagt, neben anderem:
For consistency, always use """triple double quotes""" around docstrings. Use r"""raw triple double quotes""" if you use any backslashes in your docstrings. For Unicode docstrings, use u"""Unicode triple-quoted strings""".

There are two forms of docstrings: one-liners and multi-line docstrings.
(ka, obs da noch nen aktuelleres pep gibt, dass man kennen sollte, bin da grad nicht so auf dem Laufenden)

buhtz
Beiträge: 1205
Registriert: 04.12.2015 17:54:49
Kontaktdaten:

Re: [Gelöst] Ist parsen eine regex Aufgabe?

Beitrag von buhtz » 29.03.2022 12:12:35

Ich hab noch ein AddOn. Das Pattern funktioniert nicht wenn ein Linebreak im String ist.
Soweit ich verstehe arbeitet Regex per default nur Zeilenweise. Das lässt sich aber scheinbar ändern. Hierzu finde ich \X, \s und den Punkt. Habe es auf regex101 aber bisher nicht hinbekommen.

Das hier wäre zu parsen.

Code: Alles auswählen

[[id:0c664422c239][foo bar with linebreak
in second line]]
Für mich ist OK, wenn im Ergebnis dass dann so aussieht:

Code: Alles auswählen

['0c664422c239', 'foo bar with linebreak\nin second line']
Die ID, also das zweite Feld, dürfte in meiner Situation nie Linebreaks beinhalten.

Das hier ist das ursprüngliche Pattern: \[\[id:(.+?)\]\[(.+?)\]\]
Debian 11 & 12; Desktop-PC, Headless-NAS, Raspberry Pi 4
Teil des Upstream Betreuer Teams von Back In Time (Debianbackintime)

buhtz
Beiträge: 1205
Registriert: 04.12.2015 17:54:49
Kontaktdaten:

Re: [Gelöst] Ist parsen eine regex Aufgabe?

Beitrag von buhtz » 29.03.2022 12:15:22

buhtz hat geschrieben: ↑ zum Beitrag ↑
29.03.2022 12:12:35
Das hier ist das ursprüngliche Pattern: \[\[id:(.+?)\]\[(.+?)\]\]
Jetzt hab ich's wie ich das X reinbasteln muss.

Code: Alles auswählen

\[\[id:(.+?)\]\[(.\X+?)\]\]
Funktioniert. Macht das für die erfahrenen Regexer auch Sinn? ;)
Debian 11 & 12; Desktop-PC, Headless-NAS, Raspberry Pi 4
Teil des Upstream Betreuer Teams von Back In Time (Debianbackintime)

Benutzeravatar
Meillo
Moderator
Beiträge: 9224
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: [Gelöst] Ist parsen eine regex Aufgabe?

Beitrag von Meillo » 29.03.2022 12:32:24

buhtz hat geschrieben: ↑ zum Beitrag ↑
29.03.2022 12:12:35
Soweit ich verstehe arbeitet Regex per default nur Zeilenweise. Das lässt sich aber scheinbar ändern.
Das ist korrekt. Ich kenne mich mit Python nicht aus, aber `re.MULTILINE|re.DOTALL' als drittes Argument von `findall()' koennte die Loesung sein.
Use ed once in a while!

buhtz
Beiträge: 1205
Registriert: 04.12.2015 17:54:49
Kontaktdaten:

Re: [Gelöst] Ist parsen eine regex Aufgabe?

Beitrag von buhtz » 04.04.2022 13:44:44

Debian 11 & 12; Desktop-PC, Headless-NAS, Raspberry Pi 4
Teil des Upstream Betreuer Teams von Back In Time (Debianbackintime)

buhtz
Beiträge: 1205
Registriert: 04.12.2015 17:54:49
Kontaktdaten:

Re: [Gelöst] Ist parsen eine regex Aufgabe?

Beitrag von buhtz » 17.04.2022 23:10:33

Mhm... Ich denke ich bleibe jetzt mal in diesem Thread, da sich das Thema nicht wirklich geändert, sondern nur der Schwierigkeitsgrad erhöht hat. ;)

Im Kontext von Org-Mode gibt es Links mit und ohne Label, die in dieser Form in HTML übersetzt werden.

Code: Alles auswählen

[[https://foo.bar]]
<a href="https://foo.bar">https://foo.bar</a>

[[https://foo.bar][foobar]]
<a href="https://foo.bar">foobar</a>
Ich habe für beide je auch ein RegEx (hier als Python r-String dargestellt)
  • r'\[\[(?!id\:)(.+?)\]\[(.+?)\]\]'
  • r'\[\[(?!id\:)(.+?)\]\]'
In beiden RegEx wird darauf geachtet, dass "Sonderfall"-Links die mit "[[id:" beginnen, ignoriert werden.

Jetzt der Knüller. Beide Link-Varianten kommen in einem String vor.

Code: Alles auswählen

[[https://foo.bar]] and [[https://foo.bar][foobar]]
Das erste RegEx führt im Ergebnis zu diesen beiden Gruppen

Code: Alles auswählen

https://foo.bar]] and [[https://foo.bar
foobar
Warum das passiert, kann ich einigermaßen nachvollziehen. Eine Lösung, auch einfach nur konzeptionell unabhängig von RegEx, will mir aber nicht einfallen.

Die Reihenfolge der RegEx-Varianten umzukehren hilft nicht, weil auch die Link-Varianten anders herum auftauchen können.

Also die Frage ist eigentlich, was ich hier überhaut will:
Vermutlich benötige ich zwei RegEx Pattern, eines für jede Link-Variante. Diese Pattern müssen aber die andere Link-Variante ignorieren/übersehen können.

EDIT: Beim ersten RegEx darf in Gruppe 1 kein "]]" vorkommen. Das sind also verbotene Zeichen.
Debian 11 & 12; Desktop-PC, Headless-NAS, Raspberry Pi 4
Teil des Upstream Betreuer Teams von Back In Time (Debianbackintime)

Antworten