Bitte um Hilfe bei Regulären Ausdrücken

Hallo liebe Experten,
ich habe mich heute Vormittag einige Stunden mit Regulären Ausdrücken befasst und ich verstehe es immer mehr.
Leider funktionieren aber einige Regulären Ausdrücken nicht im Devonthink die aber hier: Tools : Reguläre Ausdrücke testen funktionieren.

Ich möchte z.B. den Text der ersten Zeile eines Dokumentes extrahieren. Dafür verwende ich den Reg.Ausdruck ^(\w+)\s*(.)$ und die Ersatzgruppe \0 .
Oder ich möchte nur die ersten drei Wörter der ersten Zeile extrahieren. Dafür verwende ich den Reg.Ausdruck: ^(\w+)\s
(\w+)?\s*(\w+)?\s* mit der Ersatzgruppe \0 .
Nichts funktioniert in Devonthink.
Woran könnte das Problem liegen?
Vielen Dank für eure Hilfe
LG Holger

Besser wäre https://regex101.com, das ist wesentlich informativer und man kann die Geschmacksrichtung der RE aussuchen.

Übersetzt:

  • Matche ein Wort am Anfang der Zeile und speichere es in der ersten capturing group (^(\w+))
  • Danach muss eine beliebige Anzahl an Leerraum kommen, auch 0 Zeichen (!)
  • Und dann bis zum Zeilenende beliebig viele andere Zeichen (auch 0), aufgesammelt in der zweiten capturing group

Die “Ersatzgruppe \0” ist das gesamte Match. Du brauchst also gar keine capturing groups zu definieren, außer einer einzigen. Und “Mindestens ein Wortzeichen gefolgt von 0 oder mehr Leerzeichen gefolgt von irgendwas” ist nichts anderes als “Wortzeichen gefolgt von irgendwas”. Du sagst aber, Du wolltest die ganze erste Zeile haben – dann brauchst Du kein Wortzeichen am Anfang.

Besser:

  • Wenn Du die gesamte Zeile haben willst, dann sagst Du das am besten in der Form ^(.*)$
  • Wenn Du leere Zeilen vermeiden willst, dann ^(.+)$ (mindestens irgendein Zeichen)
  • Wenn Du Zeilen vermeiden willst, der nur Leerraum enthält, dann ^(\S+)$

Haken dabei: Was aussieht wie eine Zeile, muss nicht unbedingt eine Zeile sein. Das hängt stark von dem betrachteten Dokument ab. Wenn es ein PDF ist (mit OCR, versteht sich), solltest du das in DT erstmal in reinen Text konvertieren (dabei bleibt das PDF erhalten) und dir dann den angucken. Das ist das, was DT “sieht”, und darauf wendet es die RE an.

Das würde man simpler so schreiben:
^((:?\w+\s+){3})
Also: Am Anfang der Zeile eine capturing group, die eine non-capturing group enthält ((:?...)). Diese besteht aus mindestens einem Wort-Zeichen gefolgt von mindestens einem Leerraum (\w+\s+), und das dreimal ({3});
Vorsicht mit dem *, der tut häufig nicht das, was Du willst.

Das ist eine wenig sinnvolle Problembeschreibung. Mindestens müsstest du das Dokument zeigen, das du benutzt, und wie deine Regel (um die geht es ja vermutlich) genau aussieht. “Funktioniert nicht” sagt niemandem etwas, da es zu viele Möglichkeiten offen lässt:

  • Es passiert gar nichts
  • Es passiert nichts, aber im Protokoll erscheint eine Fehlermeldung
  • Es passiert etwas, aber nicht das Erwartete
    • DT stürzt ab
    • der Rechner steht in Flammn
    • die behandelte Datei verschwindet
    • ihr Name ändert sich
    • ihr Inhalt ändert sich
1 Like

Hallo chrillek,
vielen Dank für deine ausführliche Antwort und den guten Beispielen.
Leider habe ich immer noch ein mysteriöses Probleme.
Wenn ich davon schreibe, dass es nicht funktioniert, meine ich, dass einfach nichts passiert. Auch kein Eintrag im Protokoll. Der Dateiname ändert sich nicht.
Ich habe mit Apple Pages eine pdf Datei erstellt die ich mit hochgeladen habe. Wenn ich die Regel aus dem Screenshot anwende, wird der Dateiname wie gewünscht geändert. Wenn ich jetzt die weimar.pdf Datei neu in Devonthink importiere und erst einmal mit der Funktion „Daten/OCR/in durchsuchbares PDF“ bearbeite und dann die gleiche Regel ausführe, wird der Dateiname der weimar.pdf nicht geändert. Das könnte wohl die Ursache sein, dass bei vielen Dateien, die ich mit der OCR Funktion bearbeitet habe, die Regel nicht funktioniert. Könnte das ein Bug sein?

Ich habe aber auch gerade festgestellt, dass die Regel bei der weimar.pdf Datei (die ich noch nicht mit OCR behandelt habe) mit den Regulären Ausdrücken ^(.*)$ , ^(.+)$ , ^(\S+)$ nicht funktioniert. Es passiert nichts. Es ist zum verzweifeln
LG Holger
Devonthink-Regel
weimar.pdf (30.8 KB)

Der Text des PDF-Dokumentes beginnt mit einem Leerzeichen, weswegen der reguläre Ausdruck nicht funktioniert. Konvertiert man das PDF in reinen Text und entfernt das Leerzeichen, dann klappt’s.

1 Like

Man könnte auch in der RE den Anker ^ weglassen, denke ich

Hallol,
vielen Dank für eure Antworten die mir sehr geholfen haben.
Einen Frage hat sich mir noch gestellt. Gibt es einen Reg.Ausdruck, bei dem z.B. bei Inhalt stimmt überein XXX steht, XXX im Text gefunden wird, aber YYY ausgegeben werden soll? Und das bitte mit verschiedenen Möglichkeiten bzw. verschiedenen Wörtern in einem Reg.Ausdruck.
Es steht ja manchmal nicht das Wort im Text was man dann als Dateinamen verwenden möchte.
Danke
LG Holger

Kurze Antwort: Nicht mit einem Regulären Ausruck alleine.

Längere Antwort: Klare Beispiele sind besser als Pseudo-Code mit xx und yy. Grundsätzlich ist ein Regulärer Ausdruck ein Automat, der Muster findet. Er “ersetzt” nichts.

Das kann nur eine Funktion tun, die den regulären Ausdruck verwendet. DT bietet das in relativ simpler Form an, indem es den Zugriff auf die capturing groups in seinen Text-Aktionen erlaubt. Damit lässt sich aber das von Dir Gewünschte mE nicht realisieren: DT bietet keine Möglichkeiten, z.B. mit einer lookup table aus xx eben yy zu machen.

Du wirst also ein Script schreiben müssen. Ein relativ aufwendiges habe ich hier mal gepostet (Using a single smart rule instead of Hazel (maybe)), das geht aber weit über die Namensänderung hinaus.

Grundsätzlich würde ich das in JavaScript (! ich fasse AppleScript nicht an, und es ist für reguläre Ausdrücke auch denkbar schlecht geeignet) so machen als externes Script in einer smart rule:

function performsmartrule(records) {
  const lookuptable = { 
    "Telefon" : /Telekom|Vodafone/,
    "Arzt" : /Dr\.\s+med\./,
    "Bank" : /ING|DKB/
  };
  records.forEach(r => {
    Object.keys(lookuptable).forEach(ersetzung => {
      const muster = lookuptable[ersetzung];
      if (muster.test(r.plainText())) {

        r.name = ersetzung + ' ' + r.name();
     }
  })
 })
}

Das ist jetzt ein sehr verkürztes und vereinfachtes Beispiel. Es ändert z.B. bei jedem Dokument mit “Dr. med.” im Text den Namen zu “Arzt ”. Analog mit “Telekom oder Vodafone” => “Telekom” und “ING oder DKB” => “Bank”. In der Praxis willst Du vermutlich nicht den alten Namen, sondern etwas selbst Gebautes wie “Arzt Befund” haben.

Das wiederum kann eine smart rule erledigen, aber ich würde es auch im Script machen, weil ich das ja eh brauche. Aber das ist Geschmackssache.

Hallo,
herzlichen Dank für das Script.
Jetzt gibt es erst einmal eine Fehlermeldung
Protokoll
Die Regel sieht so bei mir aus
regwel
Und ich habe die folgende kleine Änderung vorgenommen

 "Arzt" : /Dr\.\s+med\./,
    "BSVT-Ko Erfurt" : /Kreisorganisation Erfurt/
  };

Was muss ich noch tun damit es funktioniert?
Vielen Dank
Holger

Ich hab’ das Script so korrigiert (s.o.), dass es zumindest syntaktisch korrekt ist (d.h. es sollte keine Fehlermeldung geben).

Das könnte so klappen, aber nur, wenn “BSVT…” die letzte Zeile in der Look-Up-Tabelle ist.