<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>RegEx | FDMLab@LABW</title><link>https://fdmlab.landesarchiv-bw.de/tag/regex/</link><atom:link href="https://fdmlab.landesarchiv-bw.de/tag/regex/index.xml" rel="self" type="application/rss+xml"/><description>RegEx</description><generator>Wowchemy (https://wowchemy.com)</generator><language>de-de</language><lastBuildDate>Sun, 01 May 2022 00:00:00 +0000</lastBuildDate><image><url>https://fdmlab.landesarchiv-bw.de/media/sharing.jpg</url><title>RegEx</title><link>https://fdmlab.landesarchiv-bw.de/tag/regex/</link></image><item><title>Workshop - Arbeiten mit regulären Ausdrücken</title><link>https://fdmlab.landesarchiv-bw.de/workshop/openrefine-fortgeschrittene/08-regulaere-ausdruecke/</link><pubDate>Sun, 01 May 2022 00:00:00 +0000</pubDate><guid>https://fdmlab.landesarchiv-bw.de/workshop/openrefine-fortgeschrittene/08-regulaere-ausdruecke/</guid><description>&lt;p>Ein wichtiges Werkzeug beim Arbeiten mit Daten sind reguläre Ausdrücke.
Diese werden in OpenRefine von verschiedenen Funktionen unterstützt.&lt;/p>
&lt;h2 id="einführung">Einführung&lt;/h2>
&lt;blockquote>
&lt;p>Reguläre Ausdrücke in der &lt;a href="https://docs.openrefine.org/manual/expressions#regular-expressions" target="_blank" rel="noopener">OpenRefine Dokumentation&lt;/a>.&lt;/p>
&lt;/blockquote>
&lt;div class="alert alert-note">
Dieser Workshop wurde erstellt mit OpenRefine Version 3.5.0.&lt;br>
Dieser Workshop wurde zuletzt getestet mit OpenRefine Version &lt;strong>3.9.3&lt;/strong>.
&lt;/div>
&lt;p>Mit regulären Ausdrücken können wir Muster definieren, mit denen wir bestimmte Zeichenfolgen in einem Text finden, extrahieren und/oder ersetzen können. Dies funktioniert nicht nur in Programmiersprachen wie Python oder Programmen wie OpenRefine, sondern auch in frei verfügbaren Text Editoren wie &lt;a href="https://notepad-plus-plus.org/" target="_blank" rel="noopener">Notepad++&lt;/a> oder &lt;a href="https://code.visualstudio.com/" target="_blank" rel="noopener">Visual Studio Code&lt;/a>.&lt;/p>
&lt;figure id="figure-perl-problemshttpsxkcdcom1171-von-randall-munroe-unter-cc-by-nc-lizenzhttpcreativecommonsorglicensesby-nc25">
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img alt="[Perl Problems](https://xkcd.com/1171/) von Randall Munroe unter [CC BY-NC Lizenz](http://creativecommons.org/licenses/by-nc/2.5/)." srcset="
/workshop/openrefine-fortgeschrittene/08-regulaere-ausdruecke/perl_problems_hu0e0484462f33f916343aead87d9b7933_20532_8fdf08fae82e8346817146df2a00337b.webp 400w,
/workshop/openrefine-fortgeschrittene/08-regulaere-ausdruecke/perl_problems_hu0e0484462f33f916343aead87d9b7933_20532_df861a877b6fd6a5993e9f6618d9596b.webp 760w,
/workshop/openrefine-fortgeschrittene/08-regulaere-ausdruecke/perl_problems_hu0e0484462f33f916343aead87d9b7933_20532_1200x1200_fit_q75_h2_lanczos_3.webp 1200w"
src="https://fdmlab.landesarchiv-bw.de/workshop/openrefine-fortgeschrittene/08-regulaere-ausdruecke/perl_problems_hu0e0484462f33f916343aead87d9b7933_20532_8fdf08fae82e8346817146df2a00337b.webp"
width="548"
height="205"
loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;figcaption data-pre="Abbildung&amp;nbsp;" data-post=":&amp;nbsp;" class="numbered">
&lt;a href="https://xkcd.com/1171/" target="_blank" rel="noopener">Perl Problems&lt;/a> von Randall Munroe unter &lt;a href="http://creativecommons.org/licenses/by-nc/2.5/" target="_blank" rel="noopener">CC BY-NC Lizenz&lt;/a>.
&lt;/figcaption>&lt;/figure>
&lt;p>Bei Memes zu &lt;a href="https://de.wikipedia.org/wiki/Regul%C3%A4rer_Ausdruck" target="_blank" rel="noopener">regulären Ausdrücken&lt;/a> wird wie in Abbildung 1 häufig der Eindruck erweckt, dass sie mehr Probleme erzeugen als sie tatsächlich lösen. Richtig dosiert sind sie jedoch ein hilfreiches Werkzeug bei der Datenextraktion.&lt;/p>
&lt;p>Das Vorgehen beim Entwickeln von regulären Ausdrücken unterscheidet sich von Person zu Person.
Wir zeigen hier unser bevorzugtes Vorgehen, von dem gerne abgewichen werden darf.&lt;/p>
&lt;p>Zum Entwickeln, Testen und Verstehen von regulären Ausdrücken, nutzen wir &lt;a href="https://regex101.com/" target="_blank" rel="noopener">RegEx101&lt;/a> (Alternative: &lt;a href="https://regexr.com/" target="_blank" rel="noopener">RegExr&lt;/a>).
Hier bekommen wir wie in Abbildung 2 visuelles Feedback, auf welche Textzeilen unsere regulären Ausdrücke passen und was die einzelnen Bestandteile bedeuten.&lt;/p>
&lt;figure id="figure-bildschirmfoto-von-regex101httpsregex101com-mit-art-ecmascript-einem-regulären-ausdruck-zur-extraktion-von-datumsangaben-in-der-mitte-oben-mehreren-beispielen-direkt-darunter-und-hilfreichen-informationen-auf-der-rechten-seite">
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img alt="Bildschirmfoto von [RegEx101](https://regex101.com/) mit Art *ECMAScript*, einem regulären Ausdruck zur Extraktion von **Datumsangaben** in der Mitte oben, mehreren Beispielen direkt darunter und hilfreichen Informationen auf der rechten Seite." srcset="
/workshop/openrefine-fortgeschrittene/08-regulaere-ausdruecke/regex101_hu4d42a9ea634230dd2891861f8c3240d1_195054_d53b9bb6a485b284a574d997193da119.webp 400w,
/workshop/openrefine-fortgeschrittene/08-regulaere-ausdruecke/regex101_hu4d42a9ea634230dd2891861f8c3240d1_195054_4de000c996966a66f861355dd8859f87.webp 760w,
/workshop/openrefine-fortgeschrittene/08-regulaere-ausdruecke/regex101_hu4d42a9ea634230dd2891861f8c3240d1_195054_1200x1200_fit_q75_h2_lanczos_3.webp 1200w"
src="https://fdmlab.landesarchiv-bw.de/workshop/openrefine-fortgeschrittene/08-regulaere-ausdruecke/regex101_hu4d42a9ea634230dd2891861f8c3240d1_195054_d53b9bb6a485b284a574d997193da119.webp"
width="760"
height="511"
loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;figcaption data-pre="Abbildung&amp;nbsp;" data-post=":&amp;nbsp;" class="numbered">
Bildschirmfoto von &lt;a href="https://regex101.com/" target="_blank" rel="noopener">RegEx101&lt;/a> mit Art &lt;em>ECMAScript&lt;/em>, einem regulären Ausdruck zur Extraktion von &lt;strong>Datumsangaben&lt;/strong> in der Mitte oben, mehreren Beispielen direkt darunter und hilfreichen Informationen auf der rechten Seite.
&lt;/figcaption>&lt;/figure>
&lt;p>Die Verwendung eines visuell unterstützenden Werkzeuges wie RegEx101 hat den Vorteil, dass wir einen übersichtlichen regulären Ausdruck entwickeln können, den wir dann in unsere Ursprungsanwendung, wie zum Beispiel OpenRefine, übertragen können. Ein Nachteil ist, dass zum Beispiel in OpenRefine nicht alle Features von regulären Ausdrücken unterstützt werden und der reguläre Ausdruck nachträglich ggf. angepasst werden muss.&lt;/p>
&lt;h2 id="vorbereitung">Vorbereitung&lt;/h2>
&lt;p>Wir erstellen uns eine kleine Sammlung von Beispielen für Daten, die wir mit einem regulären Ausdruck bearbeiten wollen.
Dazu ergänzen wir einige Negativbeispiele, also Beispiele, die von unserem regulären Ausdruck nicht extrahiert werden sollten.&lt;/p>
&lt;p>Die Beispiele für dieses Tutorial sind im Folgenden gelistet und wir kopieren sie in das Testfenster von &lt;a href="https://regex101.com/" target="_blank" rel="noopener">RegEx101&lt;/a>.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-plain" data-lang="plain">&lt;span class="line">&lt;span class="cl">2021-11-25 Einsteigerworkshop 1
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">2021-12-08 Einsteigerworkshop 2
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">2022-04-07 Einsteigerworkshop 3
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">2022-04-13 Einsteigerworkshop 4
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">2022-05-03 Fortgeschrittenenworkshop
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">1970-01-01
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">2005-1-1
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">- - - - - - - - - - - - - - - - - - -
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Do not match!
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">1234-56-78
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">2022-13-01
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">2022-01-32
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">12-34-56
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">abcd-ef-gh
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>
&lt;div class="alert alert-note">
&lt;div>
Wir werden bei den folgenden Aufgaben teilweise keine &amp;ldquo;perfekten&amp;rdquo; regulären Ausdrücke entwickeln,
also teilweise Treffer in der Liste der Negativbeispiele haben!
&lt;/div>
&lt;/div>
&lt;p>Reguläre Ausdrücke werden von verschiedenen Programmiersprachen und Werkzeugen unterstützt.
Dabei unterscheidet sich die Art, wie reguläre Ausdrücke als solche markiert werden.
Außerdem werden je nach Programmiersprache, Version der Programmiersprache oder Werkzeug nicht alle Features von regulären Ausdrücken unterstützt.&lt;/p>
&lt;p>In RegEx101 können wir daher ein so genanntes &lt;em>Flavor&lt;/em> für die Eingabe der regulären Ausdrücke auswählen.
Wir verwenden für unser Tutorial &amp;ldquo;ECMAScript (JavaScript)&amp;rdquo;.
Das hat den Hintergrund, dass sich GREL an der Syntax für JavaScript orientiert, auch wenn es im Hintergrund Java zur Auswertung verwendet. Reguläre Ausdrücke werden hier durch zwei Schrägstriche &lt;code>/.../&lt;/code> markiert.&lt;/p>
&lt;p>Hinter dem regulären Ausdruck gibt es optional noch Optionen.
Wir verwenden für RegEx101 die Optionen &lt;code>g&lt;/code> und &lt;code>m&lt;/code>.
Das sind die Standardoptionen, die bewirken, dass ein regulärer Ausdruck auf den kompletten Text (&lt;code>g&lt;/code> für &lt;em>global&lt;/em>) und auch Zeilen übergreifend (&lt;code>m&lt;/code> für &lt;em>multiline&lt;/em>) angewendet werden kann.&lt;/p>
&lt;p>Wir haben sie in den Beispielen explizit gesetzt, damit sie beim Kopieren und Einfügen von regulären Ausdrücken hier aus dem Tutorial nicht ungewollt deaktiviert werden. In OpenRefine benötigen wir diese Optionen für unser Tutorial nicht.&lt;/p>
&lt;h2 id="aufgabe-1-zeichenauswahl-character-classes">Aufgabe 1: Zeichenauswahl (Character Classes)&lt;/h2>
&lt;p>Wir wollen die Datumsangaben extrahieren. Diese haben das Muster &lt;code>Jahreszahl-Monat-Tag&lt;/code> bzw. &lt;code>ZahlZahlZahlZahl-ZahlZahl-ZahlZahl&lt;/code>.
Ein erster Ansatz ist es, dies direkt zu formulieren.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="sr">/(0|1|2|3|4|5|6|7|8|9)(0|1|2|3|4|5|6|7|8|9)(0|1|2|3|4|5|6|7|8|9)(0|1|2|3|4|5|6|7|8|9)-(0|1|2|3|4|5|6|7|8|9)(0|1|2|3|4|5|6|7|8|9)-(0|1|2|3|4|5|6|7|8|9)(0|1|2|3|4|5|6|7|8|9)/gm&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Mit dem Pipe-Symbol &lt;code>|&lt;/code> können wir in regulären Ausdrücken Alternativen formulieren. Also zum Beispiel &lt;code>0|1&lt;/code>.
Mit den runden Klammern &lt;code>(&lt;/code> und &lt;code>)&lt;/code> können wir die Alternativen gruppieren.&lt;/p>
&lt;p>Dies ist etwas umständlich und unleserlich. Daher gibt es in regulären Ausdrücken auch ein Muster zur Zeichenauswahl, welches die eckigen Klammern &lt;code>[&lt;/code> und &lt;code>]&lt;/code> verwendet. Mit den &lt;em>Character Classes&lt;/em> lässt sich der obige Ausdruck vereinfachen zu:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="sr">/[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]/gm&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Die Zeichenauswahl lässt sich kombinieren und limitieren.
So lassen sich Zahlen im &lt;a href="https://de.wikipedia.org/wiki/Hexadezimalsystem" target="_blank" rel="noopener">Hexadezimalsystem&lt;/a> identifizieren mit &lt;code>[0-9A-F]&lt;/code>.&lt;/p>
&lt;p>&lt;strong>Aufgabe:&lt;/strong> Passen Sie den obigen regulären Ausdruck so an, dass das erste Zeichen der Jahreszahl des Datums nur eine 1 oder 2 sein darf.&lt;/p>
&lt;details class="spoiler " id="spoiler-4">
&lt;summary>&lt;strong>Lösung:&lt;/strong>&lt;/summary>
&lt;p>&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="sr">/[1-2][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]/gm&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="sr">/(1|2)[0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]/gm&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;/p>
&lt;/details>
&lt;h2 id="aufgabe-2-zeichenklassen-shape-matching">Aufgabe 2: Zeichenklassen (Shape Matching)&lt;/h2>
&lt;p>Alternativ zu der recht flexiblen Zeichenauswahl gibt es vordefinierte Zeichenklassen, die es einfacher machen, die Form des Musters zu beschreiben.&lt;/p>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Klasse&lt;/th>
&lt;th>Steht für&lt;/th>
&lt;th>Zeichenauswahl&lt;/th>
&lt;th>Beschreibung&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>&lt;code>\d&lt;/code>&lt;/td>
&lt;td>&lt;em>digit&lt;/em>&lt;/td>
&lt;td>&lt;code>[0-9]&lt;/code>&lt;/td>
&lt;td>Beliebige Zahl&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>\w&lt;/code>&lt;/td>
&lt;td>&lt;em>word&lt;/em>&lt;/td>
&lt;td>&lt;code>[a-zA-Z0-9_]&lt;/code>&lt;/td>
&lt;td>Buchstaben in Groß- oder Kleinschreibung, Zahlen und Unterstrich.&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>\s&lt;/code>&lt;/td>
&lt;td>&lt;em>space&lt;/em>&lt;/td>
&lt;td>&lt;/td>
&lt;td>Leerraum: Leerzeichen, Tabulator, &amp;hellip;&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>\b&lt;/code>&lt;/td>
&lt;td>&lt;em>boundary&lt;/em>&lt;/td>
&lt;td>&lt;/td>
&lt;td>Wortgrenze, erfasst kein separates Zeichen.&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;p>Mit der Klasse &lt;code>\d&lt;/code> für Zahlen sieht der reguläre Ausdruck aus Aufgabe 1 wie folgt aus:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="sr">/\d\d\d\d-\d\d-\d\d/gm&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>&lt;strong>Aufgabe:&lt;/strong> Passen Sie den obigen regulären Ausdruck so an, dass er (nur) auf das Datumsformat &lt;code>2005-1-1&lt;/code> passt.&lt;/p>
&lt;details class="spoiler " id="spoiler-5">
&lt;summary>&lt;strong>Lösung:&lt;/strong>&lt;/summary>
&lt;p>&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="sr">/\d\d\d\d-\d-\d/gm&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;/p>
&lt;/details>
&lt;h2 id="aufgabe-3-verneinungen">Aufgabe 3: Verneinungen&lt;/h2>
&lt;p>Die Zeichenauswahl oder Zeichenklasse lässt sich auch negieren.
Bei der Zeichenauswahl funktioniert das mit dem Sonderzeichen &lt;code>^&lt;/code>, bei den Zeichenklassen durch Großschreibung.&lt;/p>
&lt;ul>
&lt;li>Negierte Zeichenauswahl für Zahlen: &lt;code>[^0-9]&lt;/code>&lt;/li>
&lt;li>Negierte Zeichenklasse für Zahlen: &lt;code>\D&lt;/code>&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>Aufgabe:&lt;/strong> Negieren Sie die regulären Ausdrücke für das Datum aus Aufgabe 1 und Aufgabe 2.&lt;/p>
&lt;details class="spoiler " id="spoiler-6">
&lt;summary>&lt;strong>Lösung:&lt;/strong>&lt;/summary>
&lt;p>&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="sr">/[^0-9][^0-9][^0-9][^0-9]-[^0-9][^0-9]-[^0-9][^0-9]/gm&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="sr">/\D\D\D\D-\D\D-\D\D/gm&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;/p>
&lt;/details>
&lt;h2 id="aufgabe-4-quantoren-quantifiers">Aufgabe 4: Quantoren (Quantifiers)&lt;/h2>
&lt;p>Anstatt Zeichen, Zeichenauswahl oder Zeichenklassen wiederholt zu schreiben, lassen sich Wiederholungen auch durch Quantoren definieren.&lt;/p>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Quantor&lt;/th>
&lt;th style="text-align:center">Alternative&lt;/th>
&lt;th>Beschreibung&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>&lt;code>{2,}&lt;/code>&lt;/td>
&lt;td style="text-align:center">&lt;/td>
&lt;td>Mindestens zweimal&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>{1,2}&lt;/code>&lt;/td>
&lt;td style="text-align:center">&lt;/td>
&lt;td>Mindest einmal, höchstens zweimal&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>?&lt;/code>&lt;/td>
&lt;td style="text-align:center">&lt;code>{0,1}&lt;/code>&lt;/td>
&lt;td>Kann vorkommen&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>+&lt;/code>&lt;/td>
&lt;td style="text-align:center">&lt;code>{1,}&lt;/code>&lt;/td>
&lt;td>Kann sich wiederholen&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>*&lt;/code>&lt;/td>
&lt;td style="text-align:center">&lt;code>{0,}&lt;/code>&lt;/td>
&lt;td>Kann vorkommen und sich wiederholen&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;p>Ein möglicher regulärer Ausdruck für unsere Daten wäre also:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="sr">/\d{4}-\d\d?-\d\d?/gm&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>&lt;strong>Aufgabe:&lt;/strong> Schreiben Sie den obigen regulären Ausdruck so um, dass er den &lt;code>?&lt;/code> Quantor nicht mehr verwendet.&lt;/p>
&lt;details class="spoiler " id="spoiler-7">
&lt;summary>&lt;strong>Lösung:&lt;/strong>&lt;/summary>
&lt;p>&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="sr">/\d{4}-\d{1,2}-\d{1,2}/gm&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;/p>
&lt;/details>
&lt;h2 id="aufgabe-5-gruppierungen-group-constructs">Aufgabe 5: Gruppierungen (Group Constructs)&lt;/h2>
&lt;p>Mit den runden Klammern &lt;code>(&lt;/code> und &lt;code>)&lt;/code> lassen sich Gruppen in regulären Ausdrücken definieren.
Das ist nicht nur hilfreich, wenn man mit dem Pipe Symbol &lt;code>|&lt;/code> Alternativen definieren möchte, sondern auch um einzelne Bestandteile zu markieren.&lt;/p>
&lt;p>Setzen wir die einzelnen Bestandteile des regulären Ausdrucks in runde Klammern, dann zeigt uns RegEx101 wie in Abbildung 3 in Gruppe 1 die Jahreszahl, in Gruppe 2 den Monat und in Gruppe 3 den Tag. Auch bei der Verwendung von regulären Ausdrücken in OpenRefine können wir auf die einzelnen Gruppen zugreifen.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="sr">/(\d{4})-(\d{1,2})-(\d{1,2})/gm&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>
&lt;figure id="figure-bildschirmfoto-von-regex101httpsregex101com-mit-den-extrahierten-gruppen">
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img alt="Bildschirmfoto von [RegEx101](https://regex101.com/) mit den extrahierten Gruppen." srcset="
/workshop/openrefine-fortgeschrittene/08-regulaere-ausdruecke/regex101-matches_hu6ff4b2b90356336f98034e3c0e3c37b7_8361_2c21c28cf9419ae2c6352f91bdc4e7e7.webp 400w,
/workshop/openrefine-fortgeschrittene/08-regulaere-ausdruecke/regex101-matches_hu6ff4b2b90356336f98034e3c0e3c37b7_8361_3cf30331722d19be6be1321dd2d0f58a.webp 760w,
/workshop/openrefine-fortgeschrittene/08-regulaere-ausdruecke/regex101-matches_hu6ff4b2b90356336f98034e3c0e3c37b7_8361_1200x1200_fit_q75_h2_lanczos_3.webp 1200w"
src="https://fdmlab.landesarchiv-bw.de/workshop/openrefine-fortgeschrittene/08-regulaere-ausdruecke/regex101-matches_hu6ff4b2b90356336f98034e3c0e3c37b7_8361_2c21c28cf9419ae2c6352f91bdc4e7e7.webp"
width="240"
height="189"
loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;figcaption data-pre="Abbildung&amp;nbsp;" data-post=":&amp;nbsp;" class="numbered">
Bildschirmfoto von &lt;a href="https://regex101.com/" target="_blank" rel="noopener">RegEx101&lt;/a> mit den extrahierten Gruppen.
&lt;/figcaption>&lt;/figure>
&lt;p>Die einzelnen Gruppen können auch benannt werden um dann wie in Abbildung 4 über den Gruppennamen aufgerufen werden.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="sr">/(?&amp;lt;Jahr&amp;gt;\d{4})-(?&amp;lt;Monat&amp;gt;\d{1,2})-(?&amp;lt;Tag&amp;gt;\d{1,2})/gm&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>
&lt;figure id="figure-bildschirmfoto-von-regex101httpsregex101com-mit-den-benannten-gruppen">
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img alt="Bildschirmfoto von [RegEx101](https://regex101.com/) mit den benannten Gruppen." srcset="
/workshop/openrefine-fortgeschrittene/08-regulaere-ausdruecke/regex101-named-matches_hu9071d89d65be8ab24c22d906808b7586_9563_bf933ef1ff2b0482a722865acf01410b.webp 400w,
/workshop/openrefine-fortgeschrittene/08-regulaere-ausdruecke/regex101-named-matches_hu9071d89d65be8ab24c22d906808b7586_9563_d34fac50809a666d3163e0cc294e2a2b.webp 760w,
/workshop/openrefine-fortgeschrittene/08-regulaere-ausdruecke/regex101-named-matches_hu9071d89d65be8ab24c22d906808b7586_9563_1200x1200_fit_q75_h2_lanczos_3.webp 1200w"
src="https://fdmlab.landesarchiv-bw.de/workshop/openrefine-fortgeschrittene/08-regulaere-ausdruecke/regex101-named-matches_hu9071d89d65be8ab24c22d906808b7586_9563_bf933ef1ff2b0482a722865acf01410b.webp"
width="276"
height="197"
loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;figcaption data-pre="Abbildung&amp;nbsp;" data-post=":&amp;nbsp;" class="numbered">
Bildschirmfoto von &lt;a href="https://regex101.com/" target="_blank" rel="noopener">RegEx101&lt;/a> mit den benannten Gruppen.
&lt;/figcaption>&lt;/figure>
&lt;p>&lt;strong>Aufgabe:&lt;/strong> Erstellen Sie einen regulären Ausdruck mit den zwei benannten Gruppen &lt;code>Datum&lt;/code> und &lt;code>Event&lt;/code>. Das erwartete Ergebnis ist in Abbildung 5 gezeigt.&lt;/p>
&lt;figure id="figure-bildschirmfoto-von-regex101httpsregex101com-mit-den-erwarteten-ergebnissen">
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img alt="Bildschirmfoto von [RegEx101](https://regex101.com/) mit den erwarteten Ergebnissen." srcset="
/workshop/openrefine-fortgeschrittene/08-regulaere-ausdruecke/regex101-expected-matches_hu5ce7f208bf5f90ace184f0d78ee94637_77476_ba0297e2927abc5a486f48e6310a0796.webp 400w,
/workshop/openrefine-fortgeschrittene/08-regulaere-ausdruecke/regex101-expected-matches_hu5ce7f208bf5f90ace184f0d78ee94637_77476_acc9bc2d3037731d62c49990d0a1e14d.webp 760w,
/workshop/openrefine-fortgeschrittene/08-regulaere-ausdruecke/regex101-expected-matches_hu5ce7f208bf5f90ace184f0d78ee94637_77476_1200x1200_fit_q75_h2_lanczos_3.webp 1200w"
src="https://fdmlab.landesarchiv-bw.de/workshop/openrefine-fortgeschrittene/08-regulaere-ausdruecke/regex101-expected-matches_hu5ce7f208bf5f90ace184f0d78ee94637_77476_ba0297e2927abc5a486f48e6310a0796.webp"
width="554"
height="667"
loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;figcaption data-pre="Abbildung&amp;nbsp;" data-post=":&amp;nbsp;" class="numbered">
Bildschirmfoto von &lt;a href="https://regex101.com/" target="_blank" rel="noopener">RegEx101&lt;/a> mit den erwarteten Ergebnissen.
&lt;/figcaption>&lt;/figure>
&lt;details class="spoiler " id="spoiler-11">
&lt;summary>&lt;strong>Lösung:&lt;/strong>&lt;/summary>
&lt;p>&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="sr">/(?&amp;lt;Datum&amp;gt;\d{4}-\d{1,2}-\d{1,2}) (?&amp;lt;Event&amp;gt;[a-zA-Z0-9 ]+)/gm&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="sr">/(?&amp;lt;Datum&amp;gt;\d{4}-\d{1,2}-\d{1,2}) (?&amp;lt;Event&amp;gt;.+)/gm&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;/p>
&lt;/details>
&lt;div class="alert alert-note">
&lt;div>
&lt;p>In OpenRefine 3.5, 3.6 und 3.7 werden benannte Gruppierungen nicht überall unterstützt.
Beispielsweise wird bei &lt;a href="https://docs.openrefine.org/manual/grelfunctions#finds-sub-or-p" target="_blank" rel="noopener">find()&lt;/a> immer nur der vollständige Treffer zurückgegeben und bei &lt;a href="https://docs.openrefine.org/manual/grelfunctions#matchs-p" target="_blank" rel="noopener">match()&lt;/a> die Gruppen ausschließlich durchnummeriert. Lediglich bei &lt;a href="https://docs.openrefine.org/manual/grelfunctions#replaces-s-or-p-find-s-replace" target="_blank" rel="noopener">replace()&lt;/a> lässt sich auf die benannten Gruppen zugreifen.&lt;/p>
&lt;p>Der folgende GREL Ausdruck nutzt benannte Gruppen um mit &lt;code>replace()&lt;/code> die Reihenfolge des Datums umzudrehen:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="nx">value&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">replace&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sr">/(?&amp;lt;Jahr&amp;gt;\d{4})-(?&amp;lt;Monat&amp;gt;\d{1,2})-(?&amp;lt;Tag&amp;gt;\d{1,2})/&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;${Tag}-${Monat}-${Jahr}&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>
&lt;/div>
&lt;/div>
&lt;h2 id="aufgabe-6-look-around-look-aheadlook-behind">Aufgabe 6: Look-around (Look-ahead/Look-behind)&lt;/h2>
&lt;p>Manchmal möchte man die Daten weiter einschränken.&lt;/p>
&lt;p>Hier ein einfaches Beispiel um nur Daten aus dem Jahr &lt;code>2022&lt;/code> zu extrahieren:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="sr">/2022-\d{1,2}-\d{1,2}/gm&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Aufwendiger wird es, wenn ein Datum nur extrahiert werden soll, wenn ein bestimmter Begriff dahinter steht.
Dies funktioniert mit so genannten &lt;em>Look-around&lt;/em> Anweisungen.
Man kann via &lt;em>positive Look-ahead&lt;/em> &lt;code>(?=...)&lt;/code> definieren, dass ein Begriff &lt;strong>nach&lt;/strong> einem Muster vorkommen soll und
via &lt;em>positive Look-behind&lt;/em> &lt;code>(?&amp;lt;=...)&lt;/code> kann definiert werden, dass ein Begriff &lt;strong>vor&lt;/strong> einem Muster vorkommen soll.&lt;/p>
&lt;p>So findet der folgende reguläre Ausdruck alle Daten unserer Einsteigerworkshops, ohne den Begriff &amp;ldquo;Einsteigerworkshop&amp;rdquo; mit in das Ergebnis aufzunehmen:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="sr">/\d{4}-\d{1,2}-\d{1,2}(?= Einsteigerworkshop)/gm&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Die &lt;em>Look-around&lt;/em> Anweisungen lassen sich auch verneinen, indem man das Gleichheitszeichen &lt;code>=&lt;/code> durch ein Ausrufezeichen &lt;code>!&lt;/code> austauscht.
So findet der folgende reguläre Ausdruck mit einem &lt;em>negative Look-ahead&lt;/em> &lt;code>(?!...)&lt;/code> alle Daten von &lt;strong>nicht&lt;/strong> Einsteigerworkshops:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="sr">/\d{4}-\d{1,2}-\d{1,2} (?!Einsteigerworkshop)/gm&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>&lt;strong>Aufgabe:&lt;/strong> Extrahieren Sie die Titel aller drei Workshops im Jahr 2022. Nutzen Sie dazu eine &lt;em>positive Look-behind&lt;/em> Anweisung &lt;code>(?&amp;lt;=...)&lt;/code>.&lt;/p>
&lt;details class="spoiler " id="spoiler-13">
&lt;summary>&lt;strong>Hinweise:&lt;/strong>&lt;/summary>
&lt;p>&lt;ul>
&lt;li>Quantoren wie &lt;code>+&lt;/code>, &lt;code>*&lt;/code>, &lt;code>?&lt;/code>, &lt;code>{1,9}&lt;/code> werden in &lt;em>Look-around&lt;/em> Gruppen &lt;strong>nicht überall&lt;/strong> unterstützt! Das kommt auf die benutzte Programmiersprache, deren Version und/oder verwendeten Zusatzbibliotheken an. Daher im Zweifel erst einmal testen!&lt;/li>
&lt;li>&lt;em>Look-around&lt;/em> Anweisungen verlangsamen die Auswertung eines regulären Ausdrucks deutlich und sollten daher mit Bedacht eingesetzt werden.&lt;/li>
&lt;/ul>
&lt;/p>
&lt;/details>
&lt;details class="spoiler " id="spoiler-14">
&lt;summary>&lt;strong>Lösung:&lt;/strong>&lt;/summary>
&lt;p>&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="sr">/(?&amp;lt;=2022-\d\d-\d\d )(?&amp;lt;Titel&amp;gt;[a-zA-Z0-9 ]+)/gm&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;/p>
&lt;/details>
&lt;h2 id="aufgabe-7-datums-einschränkungen">Aufgabe 7: Datums Einschränkungen&lt;/h2>
&lt;p>Mit einer Kombination von Alternativen, Gruppierungen, Zeichenauswahl und Quantoren lässt sich auch ein regulärer Ausdruck entwickeln, der ausschließlich valide Datumsangaben zwischen 1900 und 2029 extrahiert.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="sr">/(?&amp;lt;Jahr&amp;gt;19\d\d|20[0-2]\d)-(?&amp;lt;Monat&amp;gt;0?\d|1[0-2])-(?&amp;lt;Tag&amp;gt;[0-2]?\d|3[0-1])(?=\s)/gm&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Auch wenn er fachlich und technisch richtig ist, welche Probleme treten bei diesem regulären Ausdruck eventuell auf?&lt;/p>
&lt;details class="spoiler " id="spoiler-15">
&lt;summary>&lt;strong>Hinweise:&lt;/strong>&lt;/summary>
&lt;p>&lt;ul>
&lt;li>Der reguläre Ausdruck ist sehr komplex und schwer zu verstehen.&lt;/li>
&lt;li>Überflüssig da es ggf. gar keine invaliden Datumsangaben gibt?&lt;/li>
&lt;li>Ggf. möchte man falsch geschriebene Daten explizit mit in die Ergebnisse aufnehmen und nachkorrigieren?&lt;/li>
&lt;li>Ggf. Datumsangaben vor 1900 oder nach 2029 übersehen?&lt;/li>
&lt;li>Unterscheidet nicht zwischen Monaten mit 28/30 und 31 Tagen.&lt;/li>
&lt;li>&amp;hellip;&lt;/li>
&lt;/ul>
&lt;/p>
&lt;/details>
&lt;h2 id="aufgabe-8-spezielle-zeichen">Aufgabe 8: Spezielle Zeichen&lt;/h2>
&lt;p>Es gibt eine Liste mit speziellen Zeichen, die bei Vorkommen in einem regulären Ausdruck mit einem Backslash &lt;code>\&lt;/code> &lt;em>escaped&lt;/em> werden müssen um sie zu deaktivieren.&lt;/p>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Zeichen&lt;/th>
&lt;th>Bedeutung&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>&lt;code>.&lt;/code>&lt;/td>
&lt;td>Wildcard, beliebiges Zeichen&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>^&lt;/code>&lt;/td>
&lt;td>Zeilenbeginn oder Verneinung&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>$&lt;/code>&lt;/td>
&lt;td>Zeilenende&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>\&lt;/code>&lt;/td>
&lt;td>Escapezeichen&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>+&lt;/code>&lt;/td>
&lt;td>Quantor&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>*&lt;/code>&lt;/td>
&lt;td>Quantor&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>?&lt;/code>&lt;/td>
&lt;td>Quantor&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>{&lt;/code>, &lt;code>}&lt;/code>&lt;/td>
&lt;td>Quantor&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>(&lt;/code>, &lt;code>)&lt;/code>&lt;/td>
&lt;td>Gruppe&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>[&lt;/code>, &lt;code>]&lt;/code>&lt;/td>
&lt;td>Zeichenklasse&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;p>Der folgende reguläre Ausdruck passt zum Beispiel auf Zeilen, in denen nur ein Datum steht.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="sr">/^\d{4}-\d{1,2}-\d{1,2}$/gm&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>&lt;strong>Aufgabe:&lt;/strong> Schreiben Sie einen regulären Ausdruck, der in dem folgenden Text ausschließlich Dezimalzahlen in englischer Schreibweise mit Punkt &lt;code>.&lt;/code> als Trennzeichen extrahiert.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-plain" data-lang="plain">&lt;span class="line">&lt;span class="cl">Der Literpreis für Diesel ist erstmals über 2.00 Euro gestiegen.
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Siehe auch Code AFE2A00F.
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;details class="spoiler " id="spoiler-16">
&lt;summary>&lt;strong>Lösung:&lt;/strong>&lt;/summary>
&lt;p>&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="sr">/\d+\.\d+/gm&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;/p>
&lt;/details>
&lt;h2 id="aufgabe-9-reguläre-ausdrücke-in-openrefine">Aufgabe 9: Reguläre Ausdrücke in OpenRefine&lt;/h2>
&lt;p>In OpenRefine kann anstelle von Text auch häufig ein regulärer Ausdruck verwendet werden.
Zum Beispiel beim Suchen via Textfilter, dem Aufteilen von Spalten oder dem &lt;em>Replace&lt;/em>-Dialog.
Eine &lt;a href="https://docs.openrefine.org/manual/expressions#grel-supported-regex" target="_blank" rel="noopener">Liste der GREL Funktionen mit Unterstützung von regulären Ausdrücken&lt;/a> gibt es in der OpenRefine Dokumentation.&lt;/p>
&lt;p>Für diese Aufgabe wechseln wir zu OpenRefine und laden die Datei &lt;code>08_kurzbiographien.csv&lt;/code> in das Projekt &amp;ldquo;Kurzbiographien&amp;rdquo;.&lt;/p>
&lt;blockquote>
&lt;p>💾 Wir benötigen die folgende Datei (Rechtsklick und &amp;ldquo;Ziel speichern unter&amp;hellip;&amp;rdquo;):&lt;/p>
&lt;/blockquote>
&lt;a href="https://fdmlab.landesarchiv-bw.de/data/openrefine-workshop/08_kurzbiographien.csv" target="_blank">
&lt;i class="fas fa-file-csv pr-1 fa-fw">&lt;/i>Kurzbiographien als CSV&lt;/a>
&lt;blockquote>
&lt;p>Die Datei &lt;code>08_kurzbiographien.csv&lt;/code> verwendet Texte von verschiedenen und in der Datei referenzierten Wikipedia Artikeln, die unter einer &lt;a href="http://creativecommons.org/licenses/by-sa/3.0/" target="_blank" rel="noopener">CC BY-SA 3.0 Lizenz&lt;/a> veröffentlicht wurden.
Die Datei &lt;code>08_kurzbiographien.csv&lt;/code> ist entsprechend ebenfalls lizenziert unter einer &lt;a href="http://creativecommons.org/licenses/by-sa/3.0/" target="_blank" rel="noopener">CC BY-SA 3.0 Lizenz&lt;/a>.&lt;/p>
&lt;/blockquote>
&lt;p>Die Datei enthält aus Wikipedia gesammelte Kurzbiographien einiger Autoren einer bestimmten Literaturströmung.&lt;/p>
&lt;p>&lt;strong>Aufgabe:&lt;/strong> Wir wollen aus den Kurzbiographien mit Hilfe von regulären Ausdrücken vier neue Spalten erstellen:
Geburtsdatum, Geburtsort, Sterbedatum und Sterbeort.&lt;/p>
&lt;blockquote>
&lt;p>Bonusfrage: zu welcher Literaturströmung gehören die Autoren?&lt;/p>
&lt;/blockquote>
&lt;details class="spoiler " id="spoiler-18">
&lt;summary>&lt;strong>Hinweise:&lt;/strong>&lt;/summary>
&lt;p>&lt;ul>
&lt;li>Um mit einem regulären Ausdruck nur einen Teil der Daten aus einer Spalte in eine neue zu überführen bietet sich der &amp;ldquo;Add column based on this column&amp;hellip;&amp;rdquo; Dialog und die GREL Funktion &lt;a href="https://docs.openrefine.org/manual/grelfunctions#finds-sub-or-p" target="_blank" rel="noopener">find()&lt;/a> an.&lt;/li>
&lt;li>Der GREL Ausdruck &lt;code>value.find(/\d{4}/)[0]&lt;/code> findet beispielsweise alle Jahreszahlen in Form einer Liste (technisch Array) zurück und wir extrahieren mit &lt;code>[0]&lt;/code> das erste Element.&lt;/li>
&lt;li>Reguläre Ausdrücke werden in OpenRefine Funktionen mit &lt;code>/.../&lt;/code> eingefasst.&lt;/li>
&lt;/ul>
&lt;/p>
&lt;/details>
&lt;details class="spoiler " id="spoiler-19">
&lt;summary>&lt;strong>Lösung:&lt;/strong>&lt;/summary>
&lt;p>&lt;p>F&lt;/p>
&lt;p>Es gibt unterschiedliche Lösungswege, hier ist eine recht einfache Variante aufgezeigt.
Hierbei verzichten wir auf komplexe reguläre Ausdrücke und formulieren verständliche Einzelschritte.&lt;/p>
&lt;ol>
&lt;li>Neue Spalte &amp;ldquo;Geburtsdatum&amp;rdquo; erstellen via &amp;ldquo;Kurzbiographie&amp;rdquo;
&lt;i class="far fa-caret-square-down pr-1 fa-fw">&lt;/i>&amp;ldquo;Edit column&amp;rdquo;
&lt;i class="fas fa-caret-right pr-1 fa-fw">&lt;/i>&amp;ldquo;Add column based on this column&amp;hellip;&amp;rdquo; und dem GREL Ausdruck &lt;code>value.find(/\*[^;]+/)[0]&lt;/code>.&lt;/li>
&lt;li>Wiederhole Schritt 1 mit &amp;ldquo;Sterbedatum&amp;rdquo; und dem GREL Ausdruck &lt;code>value.find(/†[^\;)]+/)[0]&lt;/code>.&lt;/li>
&lt;li>Die Spalte &amp;ldquo;Geburtsdatum&amp;rdquo; in zwei Spalten aufteilen via
&amp;ldquo;Geburtsdatum&amp;rdquo;
&lt;i class="far fa-caret-square-down pr-1 fa-fw">&lt;/i>&amp;ldquo;Edit column&amp;rdquo;
&lt;i class="fas fa-caret-right pr-1 fa-fw">&lt;/i>&amp;ldquo;Split into several columns&amp;hellip;&amp;rdquo;
und dem Seperator &lt;code>\s+in\s+&lt;/code> (Häkchen bei &lt;em>regular expression&lt;/em> nicht vergessen).&lt;/li>
&lt;li>Wiederhole Schritt 3 auf der Spalte &amp;ldquo;Sterbedatum&amp;rdquo;.&lt;/li>
&lt;li>Spalten umbenennen&lt;/li>
&lt;li>Unnötige Zeichen in Spalte &amp;ldquo;Geburtsdatum&amp;rdquo; ersetzen via
&amp;ldquo;Geburtsdatum&amp;rdquo;
&lt;i class="far fa-caret-square-down pr-1 fa-fw">&lt;/i>&amp;ldquo;Edit cells&amp;rdquo;
&lt;i class="fas fa-caret-right pr-1 fa-fw">&lt;/i>&amp;ldquo;Transform&amp;hellip;&amp;rdquo;
und dem GREL Ausdruck &lt;code>value.replace(/(\*\s*|†\s*)/, &amp;quot;&amp;quot;)&lt;/code> (alternativ geht das auch über den &amp;ldquo;Replace&amp;rdquo; Dialog).&lt;/li>
&lt;li>Wiederhole Schritt 6 auf der Spalte &amp;ldquo;Sterbedatum&amp;rdquo;.&lt;/li>
&lt;/ol>
&lt;/p>
&lt;/details>
&lt;details class="spoiler " id="spoiler-20">
&lt;summary>&lt;strong>Alternative Lösung(en):&lt;/strong>&lt;/summary>
&lt;p>&lt;p>Wir verwenden &lt;code>match()&lt;/code> und einen komplexen regulären Ausdruck um alle Datenbestandteile gleichzeitig zu extrahieren:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="nx">value&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">match&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sr">/.+\* (?&amp;lt;Geburtsdatum&amp;gt;\d{1,2}\. [a-zA-Zä]+ \d{4}) in (?&amp;lt;Geburtsort&amp;gt;[^;]+); † (?&amp;lt;Sterbedatum&amp;gt;\d{1,2}\. [a-zA-Zä]+ \d{4}) in (?&amp;lt;Sterbeort&amp;gt;[^;|\)]+).+/&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Diesen GREL Ausdruck können wir dann viermal mit &amp;ldquo;Kurzbiographie&amp;rdquo;
&lt;i class="far fa-caret-square-down pr-1 fa-fw">&lt;/i>&amp;ldquo;Edit column&amp;rdquo;
&lt;i class="fas fa-caret-right pr-1 fa-fw">&lt;/i>&amp;ldquo;Add column based on this column&amp;hellip;&amp;rdquo; anwenden und jeweils via &lt;code>value.match(...)[0]&lt;/code> (Geburtsdatum) bis &lt;code>value.match(...)[3]&lt;/code> (Sterbeort) die einzelnen Bestandteile für die jeweilige Spalte extrahieren.&lt;/p>
&lt;p>Oder wir verwenden anstatt &lt;code>value.match(...)[...]&lt;/code> die Funktion &lt;code>value.match(...).join(&amp;quot;;&amp;quot;)&lt;/code> und teilen die neue Spalte anschließend an dem Trennzeichen &lt;code>;&lt;/code> in vier Spalten auf.&lt;/p>
&lt;p>Oder wir extrahieren die Daten zuerst gemeinsam und transponieren sie anschließend, wie in &lt;a href="https://fdmlab.landesarchiv-bw.de/workshop/openrefine-fortgeschrittene/11-transponieren/">Daten mit OpenRefine Transponieren&lt;/a> beschrieben.
Vor dem Transponieren müssen wir die Daten anhand von einem Zeilenumbruch &lt;code>\n&lt;/code> in mehrere Zeilen aufteilen, die Spalte anhand von &lt;code>:&lt;/code> in zwei Spalten aufteilen und mit &amp;ldquo;Edit cells&amp;rdquo;
&lt;i class="fas fa-caret-right pr-1 fa-fw">&lt;/i>&amp;ldquo;Fill down&amp;rdquo; die restlichen Spalten auffüllen.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="kd">with&lt;/span>&lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">value&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">match&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sr">/.+\* (?&amp;lt;Geburtsdatum&amp;gt;\d{1,2}\. [a-zA-Zä]+ \d{4}) in (?&amp;lt;Geburtsort&amp;gt;[^;]+); † (?&amp;lt;Sterbedatum&amp;gt;\d{1,2}\. [a-zA-Zä]+ \d{4}) in (?&amp;lt;Sterbeort&amp;gt;[^;|\)]+).+/&lt;/span>&lt;span class="p">),&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">v&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;Geburtsdatum: &amp;#34;&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="nx">v&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="mi">0&lt;/span>&lt;span class="p">]&lt;/span> &lt;span class="o">+&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;\nGeburtsort: &amp;#34;&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="nx">v&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="mi">1&lt;/span>&lt;span class="p">]&lt;/span> &lt;span class="o">+&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;\nSterbedatum: &amp;#34;&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="nx">v&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="mi">2&lt;/span>&lt;span class="p">]&lt;/span> &lt;span class="o">+&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;\nSterbeort: &amp;#34;&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="nx">v&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="mi">3&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;/p>
&lt;/details>
&lt;h2 id="aufgabe-10-vorsicht-bei-umlauten">Aufgabe 10: Vorsicht bei Umlauten&lt;/h2>
&lt;p>Wie schon erwähnt basiert OpenRefine auf Java und in der hier im Tutorial eingesetzten OpenRefine Version 3.9.3 wird Java in Version 11 mitgeliefert. Eine Übersicht über alle von Java in dieser Version unterstützen Features von regulären Ausdrücken findet sich in der &lt;a href="https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/regex/Pattern.html" target="_blank" rel="noopener">Java 11 Dokumentation zu RegEx Pattern&lt;/a>.
Die Unicode Unterstützung ist bei den Mustern in Java 11 &lt;strong>optional&lt;/strong> und muss daher separat aktiviert werden.
Das hat zur Folge, dass &amp;ldquo;Sonderzeichen&amp;rdquo; wie unsere Umlaute &lt;em>äöü&lt;/em>, oder die in der französischen Sprache gebräuchlichen Buchstaben mit Akzenten &lt;em>éêè&lt;/em>, nicht von den Mustern &lt;code>[a-z]&lt;/code> oder &lt;code>\w&lt;/code> berücksichtigt werden.&lt;/p>
&lt;p>Um zum Beispiel auch Umlaute zu berücksichtigen gibt es mehrere Möglichkeiten:&lt;/p>
&lt;ol>
&lt;li>Umlaute explizit auflisten: &lt;code>[a-zäöüß]&lt;/code>&lt;/li>
&lt;li>Spezielle Klasse für Buchstaben (&lt;em>letter&lt;/em>) verwenden: &lt;code>\p{L}&lt;/code>&lt;/li>
&lt;li>Spezielle Klasse für alphabetische Zeichen verwenden: &lt;code>\p{IsAlphabetic}&lt;/code>&lt;/li>
&lt;li>Unicode Modus mit &lt;em>inline Flag&lt;/em> aktivieren: &lt;code>(?U)\w&lt;/code>&lt;/li>
&lt;/ol>
&lt;p>&lt;strong>Aufgabe:&lt;/strong> Kopieren Sie den folgenden GREL Ausdruck in einen GREL Dialog und ersetzen Sie &lt;code>...&lt;/code> mit den oben genannten Möglichkeiten auch Unicode-Zeichen zu berücksichtigen.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="s2">&amp;#34;abcöüßéêè€$123!-&amp;#34;&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">find&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sr">/.../&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;details class="spoiler " id="spoiler-21">
&lt;summary>&lt;strong>Hinweise:&lt;/strong>&lt;/summary>
&lt;p>&lt;ul>
&lt;li>In RegEx101 wird bei der Auswahl des &lt;em>Flavors&lt;/em> Java 8 die Unicode Unterstützung über das &lt;code>U&lt;/code> Flag nach dem regulären Ausdruck aktiviert. &lt;em>Inline Flags&lt;/em> werden dort nicht unterstützt.&lt;/li>
&lt;li>In OpenRefine wird &lt;code>U&lt;/code> nur als &lt;em>inline Flag&lt;/em> und nicht als Regex Flag unterstützt.&lt;/li>
&lt;/ul>
&lt;/p>
&lt;/details>
&lt;h2 id="fazit">Fazit&lt;/h2>
&lt;p>Bei der Verwendung von regulären Ausdrücken sollte stets die Balance zwischen &lt;a href="https://en.wikipedia.org/wiki/Precision_and_recall" target="_blank" rel="noopener">Genauigkeit und Trefferquote&lt;/a> im Hinterkopf behalten werden.
Liegt die Priorität darauf nur genau die Daten zu finden, die einem sehr präzisen Muster folgen?
Oder formulieren wir das Muster eher unpräzise und filtern die überflüssigen Treffer in einem separaten Schritt?&lt;/p>
&lt;p>Wie bei der Lösung zur Aufgabe 9 angesprochen, ist es manchmal einfacher und verständlicher die Arbeiten in mehrere einfache Schritte zu teilen, anstatt sie in einem komplexen Schritt zu formulieren.
Also zum Beispiel Geburtsdatum und Geburtsort zusammenhängend zu extrahieren und dann aufzusplitten, anstatt komplexe reguläre Ausdrücke für ein Geburtsdatum &lt;strong>und&lt;/strong> den Geburtsort separat zu formulieren.&lt;/p>
&lt;hr>
&lt;p>Im nächsten Teil beschäftigen wir uns mit der Programmiersprache GREL.&lt;/p>
&lt;ul class="cta-group">
&lt;li>
&lt;a href="https://fdmlab.landesarchiv-bw.de/workshop/openrefine-fortgeschrittene/09-arbeiten-mit-grel" class="btn btn-primary px-3 py-3">09 Arbeiten mit GREL&lt;/a>
&lt;/li>
&lt;/ul></description></item><item><title>Workshop für Fortgeschrittene - Warum OpenRefine?</title><link>https://fdmlab.landesarchiv-bw.de/workshop/openrefine-fortgeschrittene/warum-openrefine/</link><pubDate>Sun, 01 May 2022 00:00:00 +0000</pubDate><guid>https://fdmlab.landesarchiv-bw.de/workshop/openrefine-fortgeschrittene/warum-openrefine/</guid><description>&lt;p>In diesem Workshop für Fortgeschrittene gehen wir tiefer in die spezialisierten Funktionalitäten von OpenRefine und beschäftigen uns mit angrenzende Themen.
Unter anderem betrachten wir reguläre Ausdrücke und programmieren mit der &lt;em>General Refine Expression Language&lt;/em> (GREL).&lt;/p>
&lt;div class="alert alert-note">
Dieser Workshop wurde erstellt mit OpenRefine Version 3.5.0.&lt;br>
Dieser Workshop wurde zuletzt getestet mit OpenRefine Version &lt;strong>3.9.3&lt;/strong>.
&lt;/div>
&lt;h2 id="inhalte-des-workshops">Inhalte des Workshops&lt;/h2>
&lt;ul>
&lt;li>Motivation: Warum OpenRefine?&lt;/li>
&lt;li>&lt;a href="https://fdmlab.landesarchiv-bw.de/workshop/openrefine-fortgeschrittene/08-regulaere-ausdruecke/">08 Reguläre Ausdrücke&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://fdmlab.landesarchiv-bw.de/workshop/openrefine-fortgeschrittene/09-arbeiten-mit-grel/">09 Arbeiten mit GREL&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://fdmlab.landesarchiv-bw.de/workshop/openrefine-fortgeschrittene/10-arbeiten-mit-records/">10 Arbeiten mit Records&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://fdmlab.landesarchiv-bw.de/workshop/openrefine-fortgeschrittene/11-transponieren/">11 Transponieren&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://fdmlab.landesarchiv-bw.de/workshop/openrefine-fortgeschrittene/12-daten-zwischen-projekten-abgleichen/">12 Daten zwischen Projekten abgleichen&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://fdmlab.landesarchiv-bw.de/workshop/openrefine-fortgeschrittene/13-die-welt-der-facets/">13 Die Welt der Facets&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://fdmlab.landesarchiv-bw.de/workshop/openrefine-fortgeschrittene/14-xml-importieren-und-exportieren/">14 XML importieren und exportieren&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://fdmlab.landesarchiv-bw.de/workshop/openrefine-fortgeschrittene/15-erweiterter-gnd-abgleich-mit-lobid/">15 Erweiterter GND Abgleich mit lobid&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://fdmlab.landesarchiv-bw.de/workshop/openrefine-fortgeschrittene/16-erweiterter-abgleich-mit-wikidata/">16 Erweiterter Abgleich mit Wikidata&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://fdmlab.landesarchiv-bw.de/workshop/openrefine-fortgeschrittene/17-erweiterter-abgleich-mit-getty/">17 Erweiterter Abgleich mit Getty&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://fdmlab.landesarchiv-bw.de/workshop/openrefine-fortgeschrittene/18-nachladen-von-geokoordinaten/">18 Nachladen von Geokoordinaten&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://fdmlab.landesarchiv-bw.de/workshop/openrefine-fortgeschrittene/19-erweitertes-clustering/">19 Erweitertes Clustering&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://fdmlab.landesarchiv-bw.de/workshop/openrefine-fortgeschrittene/20-python-mit-openrefine/">20 Python mit OpenRefine&lt;/a>&lt;/li>
&lt;/ul>
&lt;h2 id="warum-eigentlich-openrefine-für-fortgeschrittene">Warum eigentlich OpenRefine für Fortgeschrittene?&lt;/h2>
&lt;blockquote>
&lt;p>OpenRefine is Excel on steroids!&lt;/p>
&lt;/blockquote>
&lt;p>Oder um einen bildlichen Vergleich eines Workshop Teilnehmers wiederzuverwenden:&lt;/p>
&lt;blockquote>
&lt;p>Mit Excel hatten wir bisher einen Trabi.&lt;br>
Mit OpenRefine haben wir einen Ferrari bekommen.&lt;/p>
&lt;/blockquote>
&lt;p>Der Umgang mit einem solchen Werkzeug sollte jedoch geübt und vertieft werden.
Viele Funktionalitäten von OpenRefine sind über die graphische Oberfläche bedienbar.
Jedoch können einige Bearbeitungsschritte vereinfacht oder automatisiert werden.
Im &lt;a href="https://fdmlab.landesarchiv-bw.de/workshop/openrefine-einsteiger/warum-openrefine/">Workshop für Einsteiger&lt;/a> haben wir uns auf grundlegende Funktionen von OpenRefine fokussiert. Diesmal vertiefen wir einige Konzepte oder ergänzen Sie mit weiteren Technologien.&lt;/p>
&lt;p>Wir werden dabei unter anderem die Programmiersprache GREL kennen lernen.
Diese ist bei weitem nicht so mächtig, wie zum Beispiel Java oder Python.
Jedoch können wir damit schon einige Dinge automatisieren und vereinfachen.&lt;/p>
&lt;p>Außerdem werden wir uns mit regulären Ausdrücken beschäftigen.
Diese helfen uns Daten zu finden, die bestimmten Mustern entsprechen.&lt;/p>
&lt;hr>
&lt;p>Im ersten Teil machen wir einen Exkurs zum Arbeiten mit regulären Ausdrücken zur Erkennung und Extraktion von Mustern.&lt;/p>
&lt;ul class="cta-group">
&lt;li>
&lt;a href="https://fdmlab.landesarchiv-bw.de/workshop/openrefine-fortgeschrittene/08-regulaere-ausdruecke" target="_blank" rel="noopener" class="btn btn-primary px-3 py-3">08 Arbeiten mit regulären Ausdrücken&lt;/a>
&lt;/li>
&lt;/ul></description></item><item><title>Findbuch Index mit OpenRefine aufbereiten</title><link>https://fdmlab.landesarchiv-bw.de/post/2021-07-findbuch-index-mit-openrefine-aufbereiten/</link><pubDate>Tue, 27 Jul 2021 00:00:00 +0000</pubDate><guid>https://fdmlab.landesarchiv-bw.de/post/2021-07-findbuch-index-mit-openrefine-aufbereiten/</guid><description>&lt;p>In diesem Tutorial arbeiten wir mit OpenRefine und der Gemeinsamen Normdatei (GND) den Prokuratoren Index eines Findbuchs zu Akten des Reichskammergerichts auf.&lt;/p>
&lt;p>Wir haben bereits beschrieben, wie wir die &lt;a href="https://fdmlab.landesarchiv-bw.de/post/2021-07-findbuecher-mit-openrefine-in-datenbank-uebernehmen/">Einträge eines Findbuchs mit OpenRefine für den Datenbankimport aufbereiten&lt;/a>.
In diesem Beitrag geht es um die Aufarbeitung eines Indices von Findbüchern.
Wir beginnen mit dem Index der Prokuratoren.
Andere Indices folgen gegebenenfalls in weiteren Artikeln.&lt;/p>
&lt;h2 id="generelles-vorgehen">Generelles Vorgehen&lt;/h2>
&lt;p>Zur Übersichtlichkeit verwenden wir wieder das Findbuch &amp;ldquo;&lt;em>Akten des Reichskammergerichts im Staatsarchiv Wertheim - Inventar des Bestands R J 10&lt;/em>&amp;rdquo; aus dem Anhang von &amp;ldquo;&lt;em>Band 57: Akten des Reichskammergerichts im Staatsarchiv Sigmaringen - Inventar des Bestands R 7. Bearb. von Raimund J. Weber. Kohlhammer 2004&lt;/em>&amp;rdquo; mit 20 verzeichneten Archivalien.&lt;/p>
&lt;p>Die Findbücher zu den Akten des Reichskammergerichts enthalten verschiedene Indices.
Wir behandeln in diesem Tutorial den Index der Prokuratoren.&lt;/p>
&lt;figure id="figure-erste-seite-des-index-der-prokuratoren-im-findbuch-zu-bestand-r-j-10">
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img alt="Erste Seite des Index der Prokuratoren im Findbuch zu Bestand R J 10." srcset="
/post/2021-07-findbuch-index-mit-openrefine-aufbereiten/akten-rkg-band-57-wertheim-prokuratoren_hu597bc5995f23edb684e3f54eb4fc75ac_48878_65e2d36b450100349ac92bbb15a17fad.webp 400w,
/post/2021-07-findbuch-index-mit-openrefine-aufbereiten/akten-rkg-band-57-wertheim-prokuratoren_hu597bc5995f23edb684e3f54eb4fc75ac_48878_5b1a2859b02cf3bae777fdfe54e40e26.webp 760w,
/post/2021-07-findbuch-index-mit-openrefine-aufbereiten/akten-rkg-band-57-wertheim-prokuratoren_hu597bc5995f23edb684e3f54eb4fc75ac_48878_1200x1200_fit_q75_h2_lanczos_3.webp 1200w"
src="https://fdmlab.landesarchiv-bw.de/post/2021-07-findbuch-index-mit-openrefine-aufbereiten/akten-rkg-band-57-wertheim-prokuratoren_hu597bc5995f23edb684e3f54eb4fc75ac_48878_65e2d36b450100349ac92bbb15a17fad.webp"
width="491"
height="760"
loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;figcaption data-pre="Abbildung&amp;nbsp;" data-post=":&amp;nbsp;" class="numbered">
Erste Seite des Index der Prokuratoren im Findbuch zu Bestand R J 10.
&lt;/figcaption>&lt;/figure>
&lt;p>Wie in Abbildung 1 zu sehen, handelt es sich bei dem Index um ein mehrspaltiges Layout, was das Einlesen in OpenRefine verkompliziert.
Zu den einzelnen Prokuratoren finden wir eine Zuordnung von Jahren auf die Findbuchnummer(n) der verzeichneten Archivalie(n).&lt;/p>
&lt;p>Zur Aufarbeitung des Index gehen wir wie folgt vor:&lt;/p>
&lt;ol>
&lt;li>Index aus Findbuch extrahieren&lt;/li>
&lt;li>Spalten zusammenführen&lt;/li>
&lt;li>Informationen zu Prokuratoren zusammenführen&lt;/li>
&lt;li>Abgleich mit der Gemeinsamen Normdatei (GND)&lt;/li>
&lt;li>Umwandlung in internes Deskriptorenformat&lt;/li>
&lt;/ol>
&lt;p>Dabei werden wir die einzelnen Schritte in OpenRefine nicht so detailliert beschrieben,
wie in unserem &lt;a href="https://fdmlab.landesarchiv-bw.de/post/2021-07-findbuecher-mit-openrefine-in-datenbank-uebernehmen/">letzten Tutorial&lt;/a>.
Bei Bedarf, können Details zu einzelnen Schritten dort noch einmal nachgelesen werden.&lt;/p>
&lt;h2 id="1-index-aus-findbuch-extrahieren">1. Index aus Findbuch extrahieren&lt;/h2>
&lt;p>Auch bei den Indices empfiehlt es sich schon diverse Vorarbeiten im Text selbst durchzuführen.&lt;/p>
&lt;blockquote>
&lt;p>💾 Wir stellen die aufgeräumte Datei zur Verfügung (Rechtsklick und &amp;ldquo;Ziel speichern unter&amp;hellip;&amp;rdquo;):&lt;/p>
&lt;/blockquote>
&lt;a href="https://fdmlab.landesarchiv-bw.de/data/rkg-57/akten-rkg-band-57-wertheim-prokuratoren.txt" target="_blank">
&lt;i class="fas fa-file-alt pr-1 fa-fw">&lt;/i>Index Prokuratoren Akten RKG Band 57 - Wertheim&lt;/a>
.
&lt;p>Wir möchten explizit dazu einladen diese Datei zu nutzen, um die einzelnen Schritte in OpenRefine selbst auszuprobieren und damit zu experimentieren.&lt;/p>
&lt;h2 id="2-spalten-zusammenführen">2. Spalten zusammenführen&lt;/h2>
&lt;p>Wie in unserem &lt;a href="%28/post/2021-07-findbuecher-mit-openrefine-in-datenbank-uebernehmen/%29">letzten Tutorial&lt;/a> erstellen wir mit OpenRefine ein neues Projekt mit &amp;ldquo;Create Project&amp;rdquo; und laden die heruntergeladene Datei als Text.&lt;/p>
&lt;p>Um das zweispaltige Layout in ein einspaltiges Layout zu überführen, gehen wir wie in Abbildung 2 schematisch dargestellt vor:&lt;/p>
&lt;ol>
&lt;li>Die Spalte &amp;ldquo;Column 1&amp;rdquo; benennen wir in Original um.&lt;/li>
&lt;li>Wir erstellen &amp;ldquo;records&amp;rdquo; aus den einzelnen Seiten.&lt;/li>
&lt;li>Wir trennen die Spalten zeilenweise auf.&lt;/li>
&lt;li>Wir fassen die &amp;ldquo;records&amp;rdquo; in einer Zeile zusammen.&lt;/li>
&lt;li>Wir fügen die Spalten wieder zusammen.&lt;/li>
&lt;li>Wir trennen die einzelnen Zeilen wieder auf.&lt;/li>
&lt;/ol>
&lt;figure id="figure-strategie-zur-zusammenführung-der-zwei-spalten-in-mehreren-schritten">
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img alt="Strategie zur Zusammenführung der zwei Spalten in mehreren Schritten." srcset="
/post/2021-07-findbuch-index-mit-openrefine-aufbereiten/spalten-strategie_huac24e46954a78881c0c12bf53bbc59f8_128861_b0ab3ae4678151f8adfbd700719ae521.webp 400w,
/post/2021-07-findbuch-index-mit-openrefine-aufbereiten/spalten-strategie_huac24e46954a78881c0c12bf53bbc59f8_128861_8ee95a4ca4c044075125a283d62d3ae2.webp 760w,
/post/2021-07-findbuch-index-mit-openrefine-aufbereiten/spalten-strategie_huac24e46954a78881c0c12bf53bbc59f8_128861_1200x1200_fit_q75_h2_lanczos_3.webp 1200w"
src="https://fdmlab.landesarchiv-bw.de/post/2021-07-findbuch-index-mit-openrefine-aufbereiten/spalten-strategie_huac24e46954a78881c0c12bf53bbc59f8_128861_b0ab3ae4678151f8adfbd700719ae521.webp"
width="760"
height="698"
loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;figcaption data-pre="Abbildung&amp;nbsp;" data-post=":&amp;nbsp;" class="numbered">
Strategie zur Zusammenführung der zwei Spalten in mehreren Schritten.
&lt;/figcaption>&lt;/figure>
&lt;h3 id="1-spalte-in-original-umbennen">1 Spalte in Original umbennen&lt;/h3>
&lt;p>Die Umbenennung der Spalte Column 1 in Original funktioniert über &amp;ldquo;Column 1&amp;quot;
&lt;i class="far fa-caret-square-down pr-1 fa-fw">&lt;/i>&amp;quot;Edit column&amp;quot;
&lt;i class="fas fa-caret-right pr-1 fa-fw">&lt;/i>&amp;quot;Rename this column&amp;rdquo;.&lt;/p>
&lt;p>Der geladene Datensatz sieht ansclhießend wie in Abbildung 3 aus.&lt;/p>
&lt;figure id="figure-bildschirmfoto-der-geladenen-daten-ohne-bearbeitung-in-openrefine">
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img alt="Bildschirmfoto der geladenen Daten ohne Bearbeitung in OpenRefine." srcset="
/post/2021-07-findbuch-index-mit-openrefine-aufbereiten/openrefine-view-original_hu2ba9a6aa0a914fbc6b8a73a50f93f70b_45924_6c4a32aeb7c334f22b91c1fcf1f42b9a.webp 400w,
/post/2021-07-findbuch-index-mit-openrefine-aufbereiten/openrefine-view-original_hu2ba9a6aa0a914fbc6b8a73a50f93f70b_45924_de0729515253ae4be322eb4ed4792921.webp 760w,
/post/2021-07-findbuch-index-mit-openrefine-aufbereiten/openrefine-view-original_hu2ba9a6aa0a914fbc6b8a73a50f93f70b_45924_1200x1200_fit_q75_h2_lanczos_3.webp 1200w"
src="https://fdmlab.landesarchiv-bw.de/post/2021-07-findbuch-index-mit-openrefine-aufbereiten/openrefine-view-original_hu2ba9a6aa0a914fbc6b8a73a50f93f70b_45924_6c4a32aeb7c334f22b91c1fcf1f42b9a.webp"
width="417"
height="623"
loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;figcaption data-pre="Abbildung&amp;nbsp;" data-post=":&amp;nbsp;" class="numbered">
Bildschirmfoto der geladenen Daten ohne Bearbeitung in OpenRefine.
&lt;/figcaption>&lt;/figure>
&lt;h3 id="2-seiten-als-records">2 Seiten als records&lt;/h3>
&lt;p>Um die einzelnen Seiten als &amp;ldquo;records&amp;rdquo; zu markieren, erstellen wir eine neue Spalte Seite via
&amp;ldquo;Original&amp;quot;
&lt;i class="far fa-caret-square-down pr-1 fa-fw">&lt;/i>&amp;quot;Edit column&amp;quot;
&lt;i class="fas fa-caret-right pr-1 fa-fw">&lt;/i>&amp;quot;Add column based on this column&amp;hellip;&amp;rdquo;
und verwenden die folgende &amp;ldquo;expression&amp;rdquo; um die Seitennummer auszulesen.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="nx">value&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">match&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sr">/.(\d+)\s+Anhang/&lt;/span>&lt;span class="p">)[&lt;/span>&lt;span class="mi">0&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Die Seite 519 tragen wir bei der Indexüberschrift &amp;ldquo;4. Prokuratoren&amp;rdquo; von Hand ein.
Die leeren Zeilen löschen wir über das &amp;ldquo;Blank row Facet&amp;rdquo;, das wir über &amp;ldquo;All&amp;quot;
&lt;i class="far fa-caret-square-down pr-1 fa-fw">&lt;/i>&amp;quot;Facet&amp;quot;
&lt;i class="fas fa-caret-right pr-1 fa-fw">&lt;/i>&amp;quot;Facet by blank (null or empty string)&amp;rdquo; aktivieren.&lt;/p>
&lt;p>Die Spalte Seite verschieben wir anschließend an die erste Position, um pro Seite ein &amp;ldquo;record&amp;rdquo; zu haben.
Die nach Seiten organisierten &amp;ldquo;records&amp;rdquo; sehen anschließend wie in Abbildung 4 aus.&lt;/p>
&lt;figure id="figure-bildschirmfoto-von-seiten-als-records-in-openrefine">
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img alt="Bildschirmfoto von Seiten als &amp;#39;records&amp;#39; in OpenRefine." srcset="
/post/2021-07-findbuch-index-mit-openrefine-aufbereiten/openrefine-view-page_huae02a450bdafa3ae6103af45075ec205_47396_a0e501f0defa4c3b63fa4ef57baafdf9.webp 400w,
/post/2021-07-findbuch-index-mit-openrefine-aufbereiten/openrefine-view-page_huae02a450bdafa3ae6103af45075ec205_47396_f4d30a2c3d656941e59915e614587b54.webp 760w,
/post/2021-07-findbuch-index-mit-openrefine-aufbereiten/openrefine-view-page_huae02a450bdafa3ae6103af45075ec205_47396_1200x1200_fit_q75_h2_lanczos_3.webp 1200w"
src="https://fdmlab.landesarchiv-bw.de/post/2021-07-findbuch-index-mit-openrefine-aufbereiten/openrefine-view-page_huae02a450bdafa3ae6103af45075ec205_47396_a0e501f0defa4c3b63fa4ef57baafdf9.webp"
width="485"
height="626"
loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;figcaption data-pre="Abbildung&amp;nbsp;" data-post=":&amp;nbsp;" class="numbered">
Bildschirmfoto von Seiten als &amp;lsquo;records&amp;rsquo; in OpenRefine.
&lt;/figcaption>&lt;/figure>
&lt;h3 id="3-spalten-zeilenweise-auftrennen">3 Spalten zeilenweise auftrennen&lt;/h3>
&lt;p>Um die Spalten aufzuteilen, gibt es wie in Abbildung 5 gezeigt mehrere Möglichkeiten.
Es ist möglich ein Trennzeichen anzugeben, einen regulären Ausdruck zum Trennen zu verwenden, oder eine feste Spaltenbreite zu definieren.&lt;/p>
&lt;figure id="figure-dialog-zum-aufteilen-von-spalten-in-openrefine">
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img alt="Dialog zum Aufteilen von Spalten in OpenRefine." srcset="
/post/2021-07-findbuch-index-mit-openrefine-aufbereiten/openrefine-dialog-split-columns_huc8717d9a9e80e4438e3151322f96bd62_16428_56099391c518f4ce8d97477bc0e48391.webp 400w,
/post/2021-07-findbuch-index-mit-openrefine-aufbereiten/openrefine-dialog-split-columns_huc8717d9a9e80e4438e3151322f96bd62_16428_a73d8e04cd2f9402b81e8bdc964c54f3.webp 760w,
/post/2021-07-findbuch-index-mit-openrefine-aufbereiten/openrefine-dialog-split-columns_huc8717d9a9e80e4438e3151322f96bd62_16428_1200x1200_fit_q75_h2_lanczos_3.webp 1200w"
src="https://fdmlab.landesarchiv-bw.de/post/2021-07-findbuch-index-mit-openrefine-aufbereiten/openrefine-dialog-split-columns_huc8717d9a9e80e4438e3151322f96bd62_16428_56099391c518f4ce8d97477bc0e48391.webp"
width="602"
height="320"
loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;figcaption data-pre="Abbildung&amp;nbsp;" data-post=":&amp;nbsp;" class="numbered">
Dialog zum Aufteilen von Spalten in OpenRefine.
&lt;/figcaption>&lt;/figure>
&lt;p>Bei diesem Findbuch funktioniert die Auftrennung nach einer festen Spaltenbreite nicht, da zum Beispiel die linke Spalte auf Seite 519 größer ist als die linke Spalte auf Seite 520.
Also trennen wir an einer Folge von vier oder mehr Leerzeichen auf &lt;code>\s{4,}&lt;/code>.
Das hat den Nachteil, dass wir die Einrückungen in der zweiten Spalte verlieren.
Dies stört uns bei diesem Index nicht.&lt;/p>
&lt;p>Das Ergebnis ist in Abbildung 6 gezeigt.
Anschließend können wir mit &amp;ldquo;All&amp;quot;
&lt;i class="far fa-caret-square-down pr-1 fa-fw">&lt;/i>&amp;quot;Trim leading and trailing whitespace&amp;rdquo; alle unnötigen Leerzeichen in den Spalten entfernen.&lt;/p>
&lt;figure id="figure-bildschirmfoto-der-aufgeteilten-spalten-in-openrefine">
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img alt="Bildschirmfoto der aufgeteilten Spalten in OpenRefine." srcset="
/post/2021-07-findbuch-index-mit-openrefine-aufbereiten/openrefine-view-columns-separated_hu94e444ee27a95ea2c3b9fb9bbc095f17_48267_09d0753ef4861260c093db9e5ddc5513.webp 400w,
/post/2021-07-findbuch-index-mit-openrefine-aufbereiten/openrefine-view-columns-separated_hu94e444ee27a95ea2c3b9fb9bbc095f17_48267_64d5fbb0a824c839fdaac5d2597662f2.webp 760w,
/post/2021-07-findbuch-index-mit-openrefine-aufbereiten/openrefine-view-columns-separated_hu94e444ee27a95ea2c3b9fb9bbc095f17_48267_1200x1200_fit_q75_h2_lanczos_3.webp 1200w"
src="https://fdmlab.landesarchiv-bw.de/post/2021-07-findbuch-index-mit-openrefine-aufbereiten/openrefine-view-columns-separated_hu94e444ee27a95ea2c3b9fb9bbc095f17_48267_09d0753ef4861260c093db9e5ddc5513.webp"
width="486"
height="622"
loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;figcaption data-pre="Abbildung&amp;nbsp;" data-post=":&amp;nbsp;" class="numbered">
Bildschirmfoto der aufgeteilten Spalten in OpenRefine.
&lt;/figcaption>&lt;/figure>
&lt;h3 id="4-records-in-einer-zeile-zusammenfassen">4 Records in einer Zeile zusammenfassen&lt;/h3>
&lt;p>Um die Zeilen pro &amp;ldquo;record&amp;rdquo; zusammenzufassen, verwenden wir &amp;ldquo;Original 1&amp;quot;
&lt;i class="far fa-caret-square-down pr-1 fa-fw">&lt;/i>&amp;quot;Edit Cells&amp;quot;
&lt;i class="fas fa-caret-right pr-1 fa-fw">&lt;/i>&amp;quot;Join multi-valued cells&amp;hellip;&amp;rdquo; mit der Trennsequzent &lt;code>-:::-&lt;/code> und verfahren bei Spalte Original 2 ebenso.
Das Ergebnis ist in Abbildung 7 gezeigt.&lt;/p>
&lt;figure id="figure-bildschirmfoto-der-zusammengeführen-zeilen-in-openrefine">
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img alt="Bildschirmfoto der zusammengeführen Zeilen in OpenRefine." srcset="
/post/2021-07-findbuch-index-mit-openrefine-aufbereiten/openrefine-view-combine-rows_hue6af434e59adde981e531e3241be8714_37739_b13f5ce68eceddf748a276ad7ffc55a2.webp 400w,
/post/2021-07-findbuch-index-mit-openrefine-aufbereiten/openrefine-view-combine-rows_hue6af434e59adde981e531e3241be8714_37739_aec968ad586e71d4b98229f933159e7d.webp 760w,
/post/2021-07-findbuch-index-mit-openrefine-aufbereiten/openrefine-view-combine-rows_hue6af434e59adde981e531e3241be8714_37739_1200x1200_fit_q75_h2_lanczos_3.webp 1200w"
src="https://fdmlab.landesarchiv-bw.de/post/2021-07-findbuch-index-mit-openrefine-aufbereiten/openrefine-view-combine-rows_hue6af434e59adde981e531e3241be8714_37739_b13f5ce68eceddf748a276ad7ffc55a2.webp"
width="760"
height="90"
loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;figcaption data-pre="Abbildung&amp;nbsp;" data-post=":&amp;nbsp;" class="numbered">
Bildschirmfoto der zusammengeführen Zeilen in OpenRefine.
&lt;/figcaption>&lt;/figure>
&lt;h3 id="5-spalten-zusammenführen">5 Spalten zusammenführen&lt;/h3>
&lt;p>Die Spalten Original 1 und 2 werden über &amp;ldquo;Original 1&amp;quot;
&lt;i class="far fa-caret-square-down pr-1 fa-fw">&lt;/i>&amp;quot;Edit column&amp;quot;
&lt;i class="fas fa-caret-right pr-1 fa-fw">&lt;/i>&amp;quot;Join columns&amp;hellip;&amp;rdquo; wieder in der Spalte Original zusammengeführt.
Die Einstellungen sind in Abbildung 8 abgebildet.&lt;/p>
&lt;figure id="figure-dialog-zum-zusammenführen-der-spalten-in-openrefine">
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img alt="Dialog zum Zusammenführen der Spalten in OpenRefine." srcset="
/post/2021-07-findbuch-index-mit-openrefine-aufbereiten/openrefine-dialog-join-columns_hueaf9c441b3f82f5fb28bfb42466915b2_23310_d29e3bf56b195ba43e412deec5f7f2d1.webp 400w,
/post/2021-07-findbuch-index-mit-openrefine-aufbereiten/openrefine-dialog-join-columns_hueaf9c441b3f82f5fb28bfb42466915b2_23310_e03b2e749eff89a53ef193a801bcca97.webp 760w,
/post/2021-07-findbuch-index-mit-openrefine-aufbereiten/openrefine-dialog-join-columns_hueaf9c441b3f82f5fb28bfb42466915b2_23310_1200x1200_fit_q75_h2_lanczos_3.webp 1200w"
src="https://fdmlab.landesarchiv-bw.de/post/2021-07-findbuch-index-mit-openrefine-aufbereiten/openrefine-dialog-join-columns_hueaf9c441b3f82f5fb28bfb42466915b2_23310_d29e3bf56b195ba43e412deec5f7f2d1.webp"
width="760"
height="436"
loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;figcaption data-pre="Abbildung&amp;nbsp;" data-post=":&amp;nbsp;" class="numbered">
Dialog zum Zusammenführen der Spalten in OpenRefine.
&lt;/figcaption>&lt;/figure>
&lt;p>Das Ergebnis ist in Abbildung 9 gezeigt.&lt;/p>
&lt;figure id="figure-bildschirmfoto-der-zusammengeführten-spalten-in-openrefine">
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img alt="Bildschirmfoto der zusammengeführten Spalten in OpenRefine." srcset="
/post/2021-07-findbuch-index-mit-openrefine-aufbereiten/openrefine-view-combine-columns_hue77fcfc52bdf2921ba6d7c053e933957_36587_1001698c14e2e14fada1b5b3c271f4b6.webp 400w,
/post/2021-07-findbuch-index-mit-openrefine-aufbereiten/openrefine-view-combine-columns_hue77fcfc52bdf2921ba6d7c053e933957_36587_50c3b83504ad23b774cd54e7d7f03bd0.webp 760w,
/post/2021-07-findbuch-index-mit-openrefine-aufbereiten/openrefine-view-combine-columns_hue77fcfc52bdf2921ba6d7c053e933957_36587_1200x1200_fit_q75_h2_lanczos_3.webp 1200w"
src="https://fdmlab.landesarchiv-bw.de/post/2021-07-findbuch-index-mit-openrefine-aufbereiten/openrefine-view-combine-columns_hue77fcfc52bdf2921ba6d7c053e933957_36587_1001698c14e2e14fada1b5b3c271f4b6.webp"
width="760"
height="91"
loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;figcaption data-pre="Abbildung&amp;nbsp;" data-post=":&amp;nbsp;" class="numbered">
Bildschirmfoto der zusammengeführten Spalten in OpenRefine.
&lt;/figcaption>&lt;/figure>
&lt;h3 id="6-zeilen-auftrennen">6 Zeilen auftrennen&lt;/h3>
&lt;p>Um die einzelnen Zeilen wieder aufzutrennen, verwenden wir &amp;ldquo;Original&amp;quot;
&lt;i class="far fa-caret-square-down pr-1 fa-fw">&lt;/i>&amp;quot;Edit Cells&amp;quot;
&lt;i class="fas fa-caret-right pr-1 fa-fw">&lt;/i>&amp;quot;Split multi-valued cells&amp;hellip;&amp;rdquo; mit der Trennsequenz &lt;code>-:::-&lt;/code>, wie im Dialog in Abbildung 10 abgebildet.&lt;/p>
&lt;figure id="figure-dialog-zum-auftrennen-der-zeilen-in-openrefine">
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img alt="Dialog zum Auftrennen der Zeilen in OpenRefine." srcset="
/post/2021-07-findbuch-index-mit-openrefine-aufbereiten/openrefine-dialog-split-rows_hufacaa21fef3d1c9115f4f306f0dce00d_16327_572a5f30105cee4a0447a486521408d1.webp 400w,
/post/2021-07-findbuch-index-mit-openrefine-aufbereiten/openrefine-dialog-split-rows_hufacaa21fef3d1c9115f4f306f0dce00d_16327_833623c8faed1a45a74b834d3ed65749.webp 760w,
/post/2021-07-findbuch-index-mit-openrefine-aufbereiten/openrefine-dialog-split-rows_hufacaa21fef3d1c9115f4f306f0dce00d_16327_1200x1200_fit_q75_h2_lanczos_3.webp 1200w"
src="https://fdmlab.landesarchiv-bw.de/post/2021-07-findbuch-index-mit-openrefine-aufbereiten/openrefine-dialog-split-rows_hufacaa21fef3d1c9115f4f306f0dce00d_16327_572a5f30105cee4a0447a486521408d1.webp"
width="603"
height="387"
loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;figcaption data-pre="Abbildung&amp;nbsp;" data-post=":&amp;nbsp;" class="numbered">
Dialog zum Auftrennen der Zeilen in OpenRefine.
&lt;/figcaption>&lt;/figure>
&lt;p>Das Ergebnis ist in Abbildung 11 gezeigt.&lt;/p>
&lt;figure id="figure-bildschirmfoto-der-aufgetrennten-zeilen-in-openrefine">
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img alt="Bildschirmfoto der aufgetrennten Zeilen in OpenRefine." srcset="
/post/2021-07-findbuch-index-mit-openrefine-aufbereiten/openrefine-view-split-rows_hu8c6958d10e75822edc14971c48ff1f9b_34445_524485a2c51fbcfcfc5fd9d7fd9e8a40.webp 400w,
/post/2021-07-findbuch-index-mit-openrefine-aufbereiten/openrefine-view-split-rows_hu8c6958d10e75822edc14971c48ff1f9b_34445_6c30b673755eb4143cb36dd9b7467139.webp 760w,
/post/2021-07-findbuch-index-mit-openrefine-aufbereiten/openrefine-view-split-rows_hu8c6958d10e75822edc14971c48ff1f9b_34445_1200x1200_fit_q75_h2_lanczos_3.webp 1200w"
src="https://fdmlab.landesarchiv-bw.de/post/2021-07-findbuch-index-mit-openrefine-aufbereiten/openrefine-view-split-rows_hu8c6958d10e75822edc14971c48ff1f9b_34445_524485a2c51fbcfcfc5fd9d7fd9e8a40.webp"
width="328"
height="624"
loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;figcaption data-pre="Abbildung&amp;nbsp;" data-post=":&amp;nbsp;" class="numbered">
Bildschirmfoto der aufgetrennten Zeilen in OpenRefine.
&lt;/figcaption>&lt;/figure>
&lt;p>Anschließend können wir alle Zeilen mit Seitennummern entfernen und die Spalte Seite löschen.
Dafür ein &amp;ldquo;Text Facet&amp;rdquo; auf der Spalte Seite erstellen und die entsprechenden Zeilen auswählen und löschen.&lt;/p>
&lt;h2 id="3-informationen-zu-prokuratoren-zusammenführen">3. Informationen zu Prokuratoren zusammenführen&lt;/h2>
&lt;p>Wir haben in den vorangegangenen Schritten das zweispaltige Layout in ein einspaltiges Layout überführt und wollen nun für jeden Prokurator ein &amp;ldquo;record&amp;rdquo; erzeugen.
Dafür trennen wir die Zeilen in einzelne Spalten für Name, (Wirkungs-)Jahre und Verweise auf.
Anschließend transformieren wir die einzelnen Spalten, um zum Beispiel die Jahre und Verweise zusammenzufassen.&lt;/p>
&lt;h3 id="informationen-auftrennen">Informationen auftrennen&lt;/h3>
&lt;h4 id="spalte-name">Spalte Name&lt;/h4>
&lt;p>Wir erzeugen von der Spalte Original aus eine neue Spalte Name mit einer &amp;ldquo;expression&amp;rdquo;.
Dafür suchen wir mit dem regulären Ausdruck &lt;code>[A-Z].+&lt;/code> nach Zeilen, die mit einem Großbuchstaben beginnen.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="nx">value&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">match&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sr">/([A-Z].+)/&lt;/span>&lt;span class="p">)[&lt;/span>&lt;span class="mi">0&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h4 id="spalte-jahre">Spalte Jahre&lt;/h4>
&lt;p>Wir erzeugen von der Spalte Original aus eine neue Spalte Jahre mit einer &amp;ldquo;expression&amp;rdquo;.
Dafür suchen wir mit dem regulären Ausdruck &lt;code>(\d{4}):.+&lt;/code> nach Zeilen, die mit vier Zahlen gefolgt von einem Doppelpunkt beginnen.
Davon extrahieren wir die vier Zahlen.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="nx">value&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">match&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sr">/(\d{4}):.+/&lt;/span>&lt;span class="p">)[&lt;/span>&lt;span class="mi">0&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h4 id="spalte-verweise">Spalte Verweise&lt;/h4>
&lt;p>Wir erzeugen von der Spalte Original aus eine neue Spalte Verweise mit einer &amp;ldquo;expression&amp;rdquo;.
Dafür suchen wir mit dem regulären Ausdruck &lt;code>\d{4}:(.+)&lt;/code> nach Zeilen, die mit vier Zahlen gefolgt von einem Doppelpunkt beginnen.
Davon extrahieren wir alles nach dem Doppelpunkt.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="nx">value&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">match&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sr">/\d{4}:(.+)/&lt;/span>&lt;span class="p">)[&lt;/span>&lt;span class="mi">0&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="spalten-umformatieren">Spalten umformatieren&lt;/h3>
&lt;p>Die Spalte Original benötigen wir nicht mehr und können sie löschen.
Wir verschieben anschließend die Spalte Name an den Anfang, da sie die &amp;ldquo;records&amp;rdquo; definiert.&lt;/p>
&lt;p>Das Ergebnis ist in Abbildung 12 gezeigt.
Anschließend formatieren wir die einzelnen Spalten.&lt;/p>
&lt;figure id="figure-bildschirmfoto-der-extrahierten-spalten-in-openrefine">
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img alt="Bildschirmfoto der extrahierten Spalten in OpenRefine." srcset="
/post/2021-07-findbuch-index-mit-openrefine-aufbereiten/openrefine-view-extracted_huf24f13b4eaa5b1b44d55a59148a18e6d_42704_e8c9f8d35d276175f17893548835d6f2.webp 400w,
/post/2021-07-findbuch-index-mit-openrefine-aufbereiten/openrefine-view-extracted_huf24f13b4eaa5b1b44d55a59148a18e6d_42704_01db1bb85ab1b6387ea6edd89738a44b.webp 760w,
/post/2021-07-findbuch-index-mit-openrefine-aufbereiten/openrefine-view-extracted_huf24f13b4eaa5b1b44d55a59148a18e6d_42704_1200x1200_fit_q75_h2_lanczos_3.webp 1200w"
src="https://fdmlab.landesarchiv-bw.de/post/2021-07-findbuch-index-mit-openrefine-aufbereiten/openrefine-view-extracted_huf24f13b4eaa5b1b44d55a59148a18e6d_42704_e8c9f8d35d276175f17893548835d6f2.webp"
width="410"
height="623"
loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;figcaption data-pre="Abbildung&amp;nbsp;" data-post=":&amp;nbsp;" class="numbered">
Bildschirmfoto der extrahierten Spalten in OpenRefine.
&lt;/figcaption>&lt;/figure>
&lt;h4 id="spalte-jahre-1">Spalte Jahre&lt;/h4>
&lt;p>Die Jahre im Beispiel &lt;code>1797, 1767, 1770, 1801&lt;/code> wollen wir als Zeitraum im Format &lt;code>1767 - 1801&lt;/code> zusammenfassen.
Dafür führen wir die Zeilen der Spalte Jahre via &amp;ldquo;Jahre&amp;quot;
&lt;i class="far fa-caret-square-down pr-1 fa-fw">&lt;/i>&amp;quot;Edit Cells&amp;quot;
&lt;i class="fas fa-caret-right pr-1 fa-fw">&lt;/i>&amp;quot;Join multi-valued cells&amp;hellip;&amp;rdquo; mit der Trennsequenz &lt;code>,\s+&lt;/code> zusammen.&lt;/p>
&lt;p>Die Spalte Jahre transfomieren wir anschließend via &amp;ldquo;Jahre&amp;quot;
&lt;i class="far fa-caret-square-down pr-1 fa-fw">&lt;/i>&amp;quot;Edit cells&amp;quot;
&lt;i class="fas fa-caret-right pr-1 fa-fw">&lt;/i>&amp;quot;Transform&amp;hellip;&amp;rdquo;.
Dafür bestimmen wir das Minimum und das Maximum in der Liste der Zahlen.
Leider gibt es in GREL keine Funktion, die das auf einer Liste (technisch &lt;a href="https://docs.openrefine.org/manual/grelfunctions#array-functions" target="_blank" rel="noopener">Array&lt;/a>) für uns übernehmen kann. Daher gehen wir wie folgt vor:&lt;/p>
&lt;ol>
&lt;li>Wir erzeugen eine Liste &lt;code>years&lt;/code>, indem wir mit &lt;code>split()&lt;/code> an der Sequenz &lt;code>,\s+&lt;/code> trennen.&lt;/li>
&lt;li>Die einzelnen Jahre &lt;code>year&lt;/code> wandeln wir in einer &lt;code>forEach&lt;/code> Schleife mit &lt;code>toNumber()&lt;/code> in Zahlen um, da sie sonst &amp;ldquo;fehlerhaft&amp;rdquo; sortiert werden (&lt;code>&amp;quot;1, 10, 11, 2, 20, ...&amp;quot;&lt;/code>).&lt;/li>
&lt;li>Wir sortieren die Liste &lt;code>years&lt;/code> mit &lt;code>sort()&lt;/code>.&lt;/li>
&lt;li>Hat die Liste &lt;code>years&lt;/code> nur ein Jahr, dann wandeln wir es mit &lt;code>toString()&lt;/code> in Text um.&lt;/li>
&lt;li>Hat die Liste &lt;code>years&lt;/code> mehrere Elemente, nehmen wir das erste (Minimum) und das letzte Element (Maximum). Durch die Verbindung über &lt;code>-&lt;/code> wird automatisch ein Text erzeugt.&lt;/li>
&lt;/ol>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="kd">with&lt;/span>&lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">forEach&lt;/span>&lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">value&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">split&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sr">/,\s+/&lt;/span>&lt;span class="p">),&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">year&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">year&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">toNumber&lt;/span>&lt;span class="p">())&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">.&lt;/span>&lt;span class="nx">sort&lt;/span>&lt;span class="p">(),&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">years&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span>&lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">years&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">length&lt;/span>&lt;span class="p">()&lt;/span> &lt;span class="o">&amp;lt;&lt;/span> &lt;span class="mi">2&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">years&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="mi">0&lt;/span>&lt;span class="p">].&lt;/span>&lt;span class="nx">toString&lt;/span>&lt;span class="p">(),&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">years&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="mi">0&lt;/span>&lt;span class="p">]&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="s2">&amp;#34; - &amp;#34;&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="nx">years&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="o">-&lt;/span>&lt;span class="mi">1&lt;/span>&lt;span class="p">]))&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h4 id="spalte-verweise-1">Spalte Verweise&lt;/h4>
&lt;p>Die Verweise führen wir ebenfalls via &amp;ldquo;Verweise&amp;quot;
&lt;i class="far fa-caret-square-down pr-1 fa-fw">&lt;/i>&amp;quot;Edit Cells&amp;quot;
&lt;i class="fas fa-caret-right pr-1 fa-fw">&lt;/i>&amp;quot;Join multi-valued cells&amp;hellip;&amp;rdquo; mit der Trennsequenz &lt;code>,\s+&lt;/code> zusammen.&lt;/p>
&lt;p>Die Spalte Verweise transfomieren wir anschließend via &amp;ldquo;Verweise&amp;quot;
&lt;i class="far fa-caret-square-down pr-1 fa-fw">&lt;/i>&amp;quot;Edit cells&amp;quot;
&lt;i class="fas fa-caret-right pr-1 fa-fw">&lt;/i>&amp;quot;Transform&amp;hellip;&amp;rdquo;.
Bei den Verweisen haben wir mehrere Probleme:&lt;/p>
&lt;ol>
&lt;li>Teilweise werden sie als Bereiche &lt;code>8-10&lt;/code> angegeben, die wir in &lt;code>8, 9, 10&lt;/code> überführen wollen.&lt;/li>
&lt;li>Es werden zwei verschiedene Bindestriche verwendet, die optisch gleich aussehen.&lt;/li>
&lt;li>Wir können Duplikate bei den Verweisen haben.&lt;/li>
&lt;li>Die Reihenfolge kann durcheinander sein.&lt;/li>
&lt;/ol>
&lt;p>Die &amp;ldquo;expression&amp;rdquo; um diese Probleme zu behandeln, ist daher komplex.
Hier eine Erklärung des Vorgehens:&lt;/p>
&lt;ol>
&lt;li>Wir trennen die Verweise mit dem regulären Ausdruck &lt;code>,\s+&lt;/code> in eine Liste (technisch Array).&lt;/li>
&lt;li>Jeden der Verweise &lt;code>v&lt;/code> in der Liste trennen wir anschließend mit dem regulären Ausdruck &lt;code>–|\-&lt;/code> (unterschiedliche Bindestriche) und nennen das Ergebnis &lt;code>v2&lt;/code>.&lt;/li>
&lt;li>Wenn der Verweis &lt;code>v2&lt;/code> mehrere Elemente hat (es also ein Bereich mit Bindestrich war), dann erzeugen wir mit &lt;a href="https://docs.openrefine.org/manual/grel#forrangen-from-n-to-n-step-v-e" target="_blank" rel="noopener">forRange&lt;/a> eine Zahlenliste über diesem Bereich, und verbinden die Zahlen mit &lt;code>join(&amp;quot;,&amp;quot;)&lt;/code> zu einem Text.&lt;/li>
&lt;li>Jetzt haben die Bereiche und die einzelnen Verweise das gleiche Format. Also verbinden wir sie ebenfalls mit &lt;code>join(&amp;quot;,&amp;quot;)&lt;/code>.&lt;/li>
&lt;li>Den verbundenen Text trennen wir anschließend wieder mit &lt;code>,&lt;/code> in eine Liste mit einzelnen Verweisen und wandeln die einzelnen Verweise &lt;code>v&lt;/code> mit &lt;code>toNumber()&lt;/code> in Zahlen um.&lt;/li>
&lt;li>Da wir nun eine Liste mit Zahlen haben, können wir mit &lt;code>uniques()&lt;/code> die doppelten Verweise entfernen und sie mit &lt;code>sort()&lt;/code> sortieren.&lt;/li>
&lt;li>Die bereinigte Liste wandeln wir mit &lt;code>join(&amp;quot;, &amp;quot;)&lt;/code> anschließend wieder in einen Text um.&lt;/li>
&lt;/ol>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="nx">forEach&lt;/span>&lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">forEach&lt;/span>&lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">value&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">trim&lt;/span>&lt;span class="p">().&lt;/span>&lt;span class="nx">split&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sr">/,\s+/&lt;/span>&lt;span class="p">),&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">v&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kd">with&lt;/span>&lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">v&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">split&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sr">/–|\-/&lt;/span>&lt;span class="p">),&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">v2&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span>&lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">v2&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">length&lt;/span>&lt;span class="p">()&lt;/span> &lt;span class="o">&amp;gt;&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">forRange&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">v2&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="mi">0&lt;/span>&lt;span class="p">].&lt;/span>&lt;span class="nx">toNumber&lt;/span>&lt;span class="p">(),&lt;/span> &lt;span class="nx">v2&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="mi">1&lt;/span>&lt;span class="p">].&lt;/span>&lt;span class="nx">toNumber&lt;/span>&lt;span class="p">()&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">i&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">i&lt;/span>&lt;span class="p">).&lt;/span>&lt;span class="nx">join&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;,&amp;#34;&lt;/span>&lt;span class="p">),&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">v2&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="mi">0&lt;/span>&lt;span class="p">]))&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">.&lt;/span>&lt;span class="nx">join&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;,&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">.&lt;/span>&lt;span class="nx">split&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sr">/,/&lt;/span>&lt;span class="p">),&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">v&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">v&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">toNumber&lt;/span>&lt;span class="p">())&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">.&lt;/span>&lt;span class="nx">uniques&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">.&lt;/span>&lt;span class="nx">sort&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">.&lt;/span>&lt;span class="nx">join&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;, &amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h4 id="spalte-name-1">Spalte Name&lt;/h4>
&lt;p>Diese Spalte bearbeiten wir als letzte, da wir ansonsten die &amp;ldquo;record&amp;rdquo; Struktur verloren hätten.
Die &amp;ldquo;record&amp;rdquo; Struktur haben wir in den vorherigen Schritten benötigt, um die Jahre und Verweise in einer Zeile zusammenzufassen.&lt;/p>
&lt;p>Wir wollen die Spalte Name in Vorname, Nachname und Titel trennen.
Das erleichtert uns das Überführen in andere Formate zum Beispiel für den Abgleich mit der GND oder das Umwandeln in ein Deskriptorenformat.
Dafür trennen wir die Spalte Name via &amp;ldquo;Name&amp;quot;
&lt;i class="far fa-caret-square-down pr-1 fa-fw">&lt;/i>&amp;quot;Edit Cells&amp;quot;
&lt;i class="fas fa-caret-right pr-1 fa-fw">&lt;/i>&amp;quot;Split into several columns&amp;hellip;&amp;rdquo; in drei Spalten am Trennzeichen &lt;code>,&lt;/code> auf und lassen sie auch gleich entfernen.
Die entsprechenden Einstellungen sind in Abbildung 13 gezeigt.&lt;/p>
&lt;figure id="figure-dialog-zum-aufsplitten-von-spalten-in-openrefine">
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img alt="Dialog zum Aufsplitten von Spalten in OpenRefine." srcset="
/post/2021-07-findbuch-index-mit-openrefine-aufbereiten/openrefine-dialog-split-column-name_hu894663371f90b460a688eefaf20992fa_15393_a6180ff96d4f3374acfdc708b3abc96e.webp 400w,
/post/2021-07-findbuch-index-mit-openrefine-aufbereiten/openrefine-dialog-split-column-name_hu894663371f90b460a688eefaf20992fa_15393_d3017a1ee830c862c8bab71926fc3b92.webp 760w,
/post/2021-07-findbuch-index-mit-openrefine-aufbereiten/openrefine-dialog-split-column-name_hu894663371f90b460a688eefaf20992fa_15393_1200x1200_fit_q75_h2_lanczos_3.webp 1200w"
src="https://fdmlab.landesarchiv-bw.de/post/2021-07-findbuch-index-mit-openrefine-aufbereiten/openrefine-dialog-split-column-name_hu894663371f90b460a688eefaf20992fa_15393_a6180ff96d4f3374acfdc708b3abc96e.webp"
width="593"
height="317"
loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;figcaption data-pre="Abbildung&amp;nbsp;" data-post=":&amp;nbsp;" class="numbered">
Dialog zum Aufsplitten von Spalten in OpenRefine.
&lt;/figcaption>&lt;/figure>
&lt;p>Die Daten sind nun sauber aufgetrennt und können zur weiteren Verarbeitung verwendet werden.
Das Ergebnis ist in Abbildung 14 gezeigt.&lt;/p>
&lt;figure id="figure-bildschirmfoto-der-aufgeräumten-spalten-in-openrefine">
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img alt="Bildschirmfoto der aufgeräumten Spalten in OpenRefine." srcset="
/post/2021-07-findbuch-index-mit-openrefine-aufbereiten/openrefine-view-cleaned_hu463aff085d4174e8170a431698eacc5c_83868_4ff6b55f5b5ba19b5d9bfd1f305bb17a.webp 400w,
/post/2021-07-findbuch-index-mit-openrefine-aufbereiten/openrefine-view-cleaned_hu463aff085d4174e8170a431698eacc5c_83868_f8a707d7346a0e0e0f872a9ae41b7d2f.webp 760w,
/post/2021-07-findbuch-index-mit-openrefine-aufbereiten/openrefine-view-cleaned_hu463aff085d4174e8170a431698eacc5c_83868_1200x1200_fit_q75_h2_lanczos_3.webp 1200w"
src="https://fdmlab.landesarchiv-bw.de/post/2021-07-findbuch-index-mit-openrefine-aufbereiten/openrefine-view-cleaned_hu463aff085d4174e8170a431698eacc5c_83868_4ff6b55f5b5ba19b5d9bfd1f305bb17a.webp"
width="433"
height="760"
loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;figcaption data-pre="Abbildung&amp;nbsp;" data-post=":&amp;nbsp;" class="numbered">
Bildschirmfoto der aufgeräumten Spalten in OpenRefine.
&lt;/figcaption>&lt;/figure>
&lt;h2 id="4-abgleich-mit-der-gemeinsamen-normdatei">4. Abgleich mit der Gemeinsamen Normdatei&lt;/h2>
&lt;div class="mermaid">---
title: Abgleich mit GND
config:
look: handDrawn
theme: neutral
---
flowchart LR
text[fas:fa-file-alt Text]
data[fas:fa-table Table]
gnd[fas:fa-database GND]
semantic[fas:fa-project-diagram Graph]
text --> data --> semantic
gnd --> semantic
&lt;/div>
&lt;p>Als Bonus gleichen wir die Prokuratoren mit der Gemeinsamen Normdatei (GND) ab.
Der Vorgang wird in OpenRefine &lt;a href="https://docs.openrefine.org/manual/reconciling" target="_blank" rel="noopener">Reconciling&lt;/a> genannt.
Dafür verwenden wir den &lt;a href="https://lobid.org/gnd/reconcile" target="_blank" rel="noopener">GND Reconciliation Service von lobid&lt;/a>.
Die Verwendung ist in einem &lt;a href="https://blog.lobid.org/2018/08/27/openrefine.html" target="_blank" rel="noopener">lobid Blogeintrag&lt;/a> ausführlich erklärt.&lt;/p>
&lt;p>Bei uns hat sich das folgende Vorgehen bewährt.&lt;/p>
&lt;p>Zuerst erzeugen wir via &amp;ldquo;Nachname&amp;quot;
&lt;i class="far fa-caret-square-down pr-1 fa-fw">&lt;/i>&amp;quot;Edit column&amp;quot;
&lt;i class="fas fa-caret-right pr-1 fa-fw">&lt;/i>&amp;quot;Join columns&amp;hellip;&amp;rdquo; eine neue Spalte Name, wo wir die Namensstruktur &amp;ldquo;Nachname, Vorname&amp;rdquo; der GND übernehmen. &lt;sup id="fnref:1">&lt;a href="#fn:1" class="footnote-ref" role="doc-noteref">1&lt;/a>&lt;/sup>
Anschließend können wir via &amp;ldquo;Name&amp;quot;
&lt;i class="far fa-caret-square-down pr-1 fa-fw">&lt;/i>&amp;quot;Reconcile&amp;quot;
&lt;i class="fas fa-caret-right pr-1 fa-fw">&lt;/i>&amp;quot;Start reconciling&amp;rdquo; den Vorgang starten.&lt;/p>
&lt;p>Falls noch nicht geschehen, den &amp;ldquo;lobid gnd service&amp;rdquo; via &amp;ldquo;Add Standard Service&amp;hellip;&amp;rdquo; mit der URL &lt;code>https://lobid.org/gnd/reconcile&lt;/code> hinzufügen und auswählen.&lt;/p>
&lt;p>Die entsprechenden Einstellungen für den Abgleichvorgang sind in Abbildung 15 abgebildet.
Wir fügen den Titel als separate Spalte hinzu, da wir dadurch bessere Ergebnisse erzielen konnten.
Leider können wir die (Wirkungs-)Jahre nicht berücksichtigen, da es keine kleiner/größer Operation für den &amp;ldquo;Reconciliation Service&amp;rdquo; gibt.&lt;/p>
&lt;figure id="figure-dialog-zum-abgleich-der-daten-mit-dem-lobid-gnd-service">
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img alt="Dialog zum Abgleich der Daten mit dem &amp;#39;lobid gnd service&amp;#39;." srcset="
/post/2021-07-findbuch-index-mit-openrefine-aufbereiten/openrefine-dialog-reconciling_hu65f1cead5469c2f390a184a0aa06890a_31389_6fe0942761dbfe137f3afb91b3b90f91.webp 400w,
/post/2021-07-findbuch-index-mit-openrefine-aufbereiten/openrefine-dialog-reconciling_hu65f1cead5469c2f390a184a0aa06890a_31389_52b33c06393eb5fcc169f76fb4bcee6f.webp 760w,
/post/2021-07-findbuch-index-mit-openrefine-aufbereiten/openrefine-dialog-reconciling_hu65f1cead5469c2f390a184a0aa06890a_31389_1200x1200_fit_q75_h2_lanczos_3.webp 1200w"
src="https://fdmlab.landesarchiv-bw.de/post/2021-07-findbuch-index-mit-openrefine-aufbereiten/openrefine-dialog-reconciling_hu65f1cead5469c2f390a184a0aa06890a_31389_6fe0942761dbfe137f3afb91b3b90f91.webp"
width="760"
height="508"
loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;figcaption data-pre="Abbildung&amp;nbsp;" data-post=":&amp;nbsp;" class="numbered">
Dialog zum Abgleich der Daten mit dem &amp;rsquo;lobid gnd service'.
&lt;/figcaption>&lt;/figure>
&lt;div class="alert alert-warning">
&lt;div>
Beim &amp;ldquo;reconciling&amp;rdquo; werden die Inhalte der ausgewählten Spalten an einen Webservice übertragen!
Sollte das nicht gewünscht sein, ist es auch möglich einen &lt;a href="https://docs.openrefine.org/manual/reconciling#sources" target="_blank" rel="noopener">lokalen &amp;ldquo;reconciliation services&amp;rdquo; einzurichten&lt;/a>.
&lt;/div>
&lt;/div>
&lt;p>Das Ergebnis ist in Abbildung 16 gezeigt.
Jetzt können mit einer Mischung aus Heuristik (zum Beispiel alle Treffer mit Übereinstimmung von mehr als 95 % automatisch übernehmen) und manueller Prüfung die einzelnen Personen verknüpft werden.&lt;/p>
&lt;figure id="figure-bildschirmfoto-der-abzugleichenden-daten-in-openrefine">
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img alt="Bildschirmfoto der abzugleichenden Daten in OpenRefine." srcset="
/post/2021-07-findbuch-index-mit-openrefine-aufbereiten/openrefine-view-reconciling_hu793d3893f9916509064db87505e42eac_60998_2d92aa2f705b1d471c46593b3451f1cb.webp 400w,
/post/2021-07-findbuch-index-mit-openrefine-aufbereiten/openrefine-view-reconciling_hu793d3893f9916509064db87505e42eac_60998_906788d58e206443d83af025a5b42261.webp 760w,
/post/2021-07-findbuch-index-mit-openrefine-aufbereiten/openrefine-view-reconciling_hu793d3893f9916509064db87505e42eac_60998_1200x1200_fit_q75_h2_lanczos_3.webp 1200w"
src="https://fdmlab.landesarchiv-bw.de/post/2021-07-findbuch-index-mit-openrefine-aufbereiten/openrefine-view-reconciling_hu793d3893f9916509064db87505e42eac_60998_2d92aa2f705b1d471c46593b3451f1cb.webp"
width="760"
height="674"
loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;figcaption data-pre="Abbildung&amp;nbsp;" data-post=":&amp;nbsp;" class="numbered">
Bildschirmfoto der abzugleichenden Daten in OpenRefine.
&lt;/figcaption>&lt;/figure>
&lt;p>Anschließend wollen wir die GND-ID als zusätzliche Spalte in unserem Datensatz haben.
Das funktioniert über &amp;ldquo;Name&amp;quot;
&lt;i class="far fa-caret-square-down pr-1 fa-fw">&lt;/i>&amp;quot;Edit columns&amp;quot;
&lt;i class="fas fa-caret-right pr-1 fa-fw">&lt;/i>&amp;quot;Add columns from reconciled values&amp;hellip;&amp;rdquo;, wo wir die GND-ID wie in dem in Abbildung 17 dargestellten Dialog auswählen können.&lt;/p>
&lt;figure id="figure-dialog-zum-auswählen-zusätzlicher-spalten-von-abgeglichenen-daten">
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img alt="Dialog zum Auswählen zusätzlicher Spalten von abgeglichenen Daten." srcset="
/post/2021-07-findbuch-index-mit-openrefine-aufbereiten/openrefine-dialog-add-reconciled-values_hud22c0c49ded872e458cd53d27161c8bc_42820_d83127f15f475b64d5e1f8fbf97918bf.webp 400w,
/post/2021-07-findbuch-index-mit-openrefine-aufbereiten/openrefine-dialog-add-reconciled-values_hud22c0c49ded872e458cd53d27161c8bc_42820_338758e2eb8cc7252e2400a01c6ffc57.webp 760w,
/post/2021-07-findbuch-index-mit-openrefine-aufbereiten/openrefine-dialog-add-reconciled-values_hud22c0c49ded872e458cd53d27161c8bc_42820_1200x1200_fit_q75_h2_lanczos_3.webp 1200w"
src="https://fdmlab.landesarchiv-bw.de/post/2021-07-findbuch-index-mit-openrefine-aufbereiten/openrefine-dialog-add-reconciled-values_hud22c0c49ded872e458cd53d27161c8bc_42820_d83127f15f475b64d5e1f8fbf97918bf.webp"
width="760"
height="562"
loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;figcaption data-pre="Abbildung&amp;nbsp;" data-post=":&amp;nbsp;" class="numbered">
Dialog zum Auswählen zusätzlicher Spalten von abgeglichenen Daten.
&lt;/figcaption>&lt;/figure>
&lt;p>Wir konnten 18 der 37 Prokuratoren aus unserem Datensatz in der GND identifizieren und verknüpfen.
Das Ergebnis ist in Abbildung 18 gezeigt.&lt;/p>
&lt;figure id="figure-bildschirmfoto-der-abgeglichenen-daten-in-openrefine">
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img alt="Bildschirmfoto der abgeglichenen Daten in OpenRefine." srcset="
/post/2021-07-findbuch-index-mit-openrefine-aufbereiten/openrefine-view-reconciling-finished_hu69702fd179a6954bc1dbe11caa8f1ddd_84094_fe3a14533460e500c4e185162eede35b.webp 400w,
/post/2021-07-findbuch-index-mit-openrefine-aufbereiten/openrefine-view-reconciling-finished_hu69702fd179a6954bc1dbe11caa8f1ddd_84094_7576ed1a9417270918eb1447b1e3f13d.webp 760w,
/post/2021-07-findbuch-index-mit-openrefine-aufbereiten/openrefine-view-reconciling-finished_hu69702fd179a6954bc1dbe11caa8f1ddd_84094_1200x1200_fit_q75_h2_lanczos_3.webp 1200w"
src="https://fdmlab.landesarchiv-bw.de/post/2021-07-findbuch-index-mit-openrefine-aufbereiten/openrefine-view-reconciling-finished_hu69702fd179a6954bc1dbe11caa8f1ddd_84094_fe3a14533460e500c4e185162eede35b.webp"
width="760"
height="527"
loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;figcaption data-pre="Abbildung&amp;nbsp;" data-post=":&amp;nbsp;" class="numbered">
Bildschirmfoto der abgeglichenen Daten in OpenRefine.
&lt;/figcaption>&lt;/figure>
&lt;h2 id="5-umwandlung-in-deskriptorenformat">5. Umwandlung in Deskriptorenformat&lt;/h2>
&lt;p>Aus den einzelnen Datenbestandteilen können wir nun einen Deskriptor für unser AFIS zusammensetzen.
Dafür gehen wir zu einer beliebigen Spalte, um von dort aus mit einer &amp;ldquo;expression&amp;rdquo; eine neue Spalte Deskriptor im Format &lt;code>Nachname, Vorname Titel; Prokurator am Reichskammergericht {Wirkungsjahre} | {Optionale GND-ID}&lt;/code> zu erzeugen. &lt;sup id="fnref:2">&lt;a href="#fn:2" class="footnote-ref" role="doc-noteref">2&lt;/a>&lt;/sup>&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="nx">cells&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s2">&amp;#34;Nachname&amp;#34;&lt;/span>&lt;span class="p">].&lt;/span>&lt;span class="nx">value&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">trim&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="o">+&lt;/span> &lt;span class="s2">&amp;#34;, &amp;#34;&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="nx">cells&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s2">&amp;#34;Vorname&amp;#34;&lt;/span>&lt;span class="p">].&lt;/span>&lt;span class="nx">value&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">trim&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="o">+&lt;/span> &lt;span class="s2">&amp;#34; &amp;#34;&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="nx">cells&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s2">&amp;#34;Titel&amp;#34;&lt;/span>&lt;span class="p">].&lt;/span>&lt;span class="nx">value&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">trim&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="o">+&lt;/span> &lt;span class="s2">&amp;#34;; Prokurator am Reichskammergericht &amp;#34;&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="nx">cells&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s2">&amp;#34;Jahre&amp;#34;&lt;/span>&lt;span class="p">].&lt;/span>&lt;span class="nx">value&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">trim&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="o">+&lt;/span> &lt;span class="k">if&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">isNonBlank&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">cells&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s2">&amp;#34;GND-Nummer&amp;#34;&lt;/span>&lt;span class="p">]),&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34; | &amp;#34;&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="nx">cells&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s2">&amp;#34;GND-Nummer&amp;#34;&lt;/span>&lt;span class="p">].&lt;/span>&lt;span class="nx">value&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Das Endergebnis ist in Abbildung 19 gezeigt.&lt;/p>
&lt;figure id="figure-bildschirmfoto-der-umgewandelten-und-abgeglichenen-daten-mit-openrefine">
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img alt="Bildschirmfoto der umgewandelten und abgeglichenen Daten mit OpenRefine." srcset="
/post/2021-07-findbuch-index-mit-openrefine-aufbereiten/openrefine-view-finished_hu29bcaf6f7a4df5698297eae91e3ec768_92027_5450e0a3e5e5dbca8bc688f9c2d566d4.webp 400w,
/post/2021-07-findbuch-index-mit-openrefine-aufbereiten/openrefine-view-finished_hu29bcaf6f7a4df5698297eae91e3ec768_92027_de83b705a2b7158d2ffab4062fb2ed45.webp 760w,
/post/2021-07-findbuch-index-mit-openrefine-aufbereiten/openrefine-view-finished_hu29bcaf6f7a4df5698297eae91e3ec768_92027_1200x1200_fit_q75_h2_lanczos_3.webp 1200w"
src="https://fdmlab.landesarchiv-bw.de/post/2021-07-findbuch-index-mit-openrefine-aufbereiten/openrefine-view-finished_hu29bcaf6f7a4df5698297eae91e3ec768_92027_5450e0a3e5e5dbca8bc688f9c2d566d4.webp"
width="760"
height="452"
loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;figcaption data-pre="Abbildung&amp;nbsp;" data-post=":&amp;nbsp;" class="numbered">
Bildschirmfoto der umgewandelten und abgeglichenen Daten mit OpenRefine.
&lt;/figcaption>&lt;/figure>
&lt;blockquote>
&lt;p>💾 Die einzelnen Arbeitsschritte im OpenRefine Format:&lt;/p>
&lt;/blockquote>
&lt;a href="https://fdmlab.landesarchiv-bw.de/data/rkg-57/akten-rkg-band-57-wertheim-openrefine-prokuratoren.json" target="_blank">
&lt;i class="fas fa-file-archive pr-1 fa-fw">&lt;/i>Index Prokuratoren Akten RKG Band 57 - Wertheim als OpenRefine Arbeitsschritte&lt;/a>
.
&lt;h2 id="fazit">Fazit&lt;/h2>
&lt;p>Wir haben mit OpenRefine den Prokuratoren Index eines Findbuchs zu Akten des Reichskammergerichts aus einem zweispaltigen Layout in ein einspaltiges Layout überführt, den Datensatz aufbereitet und die einzelnen Prokuratoren mit der GND abgeglichen.&lt;/p>
&lt;p>Die Operationen zum Aufräumen der Daten (Jahre und Verweise) waren diesmal komplex, lassen sich jedoch auf ähnliche Probleme übertragen.&lt;/p>
&lt;p>Es bleibt die Erkenntnis, dass der Abgleich von Personen mit dem &amp;ldquo;Reconciliation Service&amp;rdquo; von lobid deutlich komfortabler wäre, wenn es möglich wäre eine zeitliche Einschränkung der Lebens- und Wirkungsdaten vorzunehmen. &lt;sup id="fnref:3">&lt;a href="#fn:3" class="footnote-ref" role="doc-noteref">3&lt;/a>&lt;/sup>&lt;/p>
&lt;div class="footnotes" role="doc-endnotes">
&lt;hr>
&lt;ol>
&lt;li id="fn:1">
&lt;p>Die Zuordnung der Daten erfolgt über den &amp;ldquo;Reconciliation Service&amp;rdquo;. Manche verwenden Verfahren, bei denen eine Übereinstimmung im Format relevant ist und zu besseren Ergebnissen führt. Andere verwenden Verfahren, bei denen die Reihenfolge der Suchbegriffe komplett ignoriert wird.&amp;#160;&lt;a href="#fnref:1" class="footnote-backref" role="doc-backlink">&amp;#x21a9;&amp;#xfe0e;&lt;/a>&lt;/p>
&lt;/li>
&lt;li id="fn:2">
&lt;p>Uns ist gegen Ende aufgefallen, dass wir noch überflüssige Leerzeichen in den einzelnen Spalten haben. Anstatt sie im Deskriptor mit &lt;code>trim()&lt;/code> zu entfernen, wäre es sinnvoller gewesen sie vorher mit &amp;ldquo;All&amp;quot;
&lt;i class="far fa-caret-square-down pr-1 fa-fw">&lt;/i>&amp;quot;Trim leading and trailing whitespace&amp;rdquo; zu entfernen.&amp;#160;&lt;a href="#fnref:2" class="footnote-backref" role="doc-backlink">&amp;#x21a9;&amp;#xfe0e;&lt;/a>&lt;/p>
&lt;/li>
&lt;li id="fn:3">
&lt;p>&lt;strong>Update April 2022&lt;/strong>: Durch ein Update in dem lobid GND API für OpenRefine kann nun eine zeitliche Einschränkung beim Reconciliation vorgenommen werden. Details dazu finden sich unter &lt;a href="https://github.com/hbz/lobid-gnd/issues/304" target="_blank" rel="noopener">Using range query parameter via OpenRefine Reconciliation&lt;/a> auf GitHub und unter &lt;a href="https://fdmlab.landesarchiv-bw.de/workshop/openrefine-fortgeschrittene/15-erweiterter-gnd-abgleich-mit-lobid/">Erweiterter GND Abgleich mit lobid&lt;/a> auf unserem Blog.&amp;#160;&lt;a href="#fnref:3" class="footnote-backref" role="doc-backlink">&amp;#x21a9;&amp;#xfe0e;&lt;/a>&lt;/p>
&lt;/li>
&lt;/ol>
&lt;/div></description></item><item><title>Findbücher mit OpenRefine in Datenbank übernehmen</title><link>https://fdmlab.landesarchiv-bw.de/post/2021-07-findbuecher-mit-openrefine-in-datenbank-uebernehmen/</link><pubDate>Tue, 20 Jul 2021 00:00:00 +0000</pubDate><guid>https://fdmlab.landesarchiv-bw.de/post/2021-07-findbuecher-mit-openrefine-in-datenbank-uebernehmen/</guid><description>&lt;p>In diesem ausführlichen Tutorial wandeln wir mit OpenRefine ein Findbuch zu Akten des Reichskammergerichts in ein AFIS kompatibles Importformat um.
Hierbei setzen wir gezielt einfache und verständliche Techniken ein.&lt;/p>
&lt;div class="alert alert-note">
&lt;div>
Dieses Tutorial ist so geschrieben, dass die einzelnen Schritte direkt in einer eigenen OpenRefine Umgebung nachvollzogen werden können.
Die benötigten Dateien stehen im Laufe des Tutorials als 💾 Download zur Verfügung.
&lt;/div>
&lt;/div>
&lt;h2 id="findbuchdigitalisierung">Findbuchdigitalisierung&lt;/h2>
&lt;p>Wir haben im FDMLab unterschiedliche Findbücher digitalisiert und in unser AFIS überführt.
Teilweise existierten die Findbücher als Word-Dateien, teilweise als PDF und teilweise ausschließlich als analoge Bücher.
Über unseren &lt;a href="https://fdmlab.landesarchiv-bw.de/post/2021-06-wie-wir-gedruckte-findbuecher-in-unsere-datenbank-bekommen/">Workflow beim Digitalisieren von Findbüchern&lt;/a>
und über die &lt;a href="https://fdmlab.landesarchiv-bw.de/post/2021-07-analoge-findbuecher-in-db-uebernehmen/">Bedeutung von regulären Ausdrücken bei der Textextraktion&lt;/a>
haben wir schon berichtet.&lt;/p>
&lt;p>Um einen hohen Automatisierungsgrad zu erreichen, haben wir Technologien wie
&lt;a href="https://fdmlab.landesarchiv-bw.de/post/2021-06-wie-wir-docker-einsetzen/">Docker&lt;/a>,
&lt;a href="https://fdmlab.landesarchiv-bw.de/post/2021-08-warum-wir-jupyter-lieben/">Jupyter NoteBooks&lt;/a>,
&lt;a href="https://fdmlab.landesarchiv-bw.de/post/2021-08-weshalb-wir-python-nutzen/">Python&lt;/a>,
&lt;a href="https://github.com/flairNLP/flair/" target="_blank" rel="noopener">flairNLP&lt;/a> und &lt;a href="https://spacy.io/" target="_blank" rel="noopener">spaCy&lt;/a> eingesetzt.&lt;/p>
&lt;p>Das ist sinnvoll, wenn - wie im Fall der Findbücher zu den Akten des Reichskammergerichts - mehrere Findbücher mit ähnlicher Struktur existieren.
Die Beherrschung dieser Technologien setzt jedoch technische Grundkenntnisse voraus, deren Aneignung recht zeitintensiv ist.&lt;/p>
&lt;p>Daher stellen wir mit OpenRefine eine Möglichkeit vor, wie Findbücher semimanuell für den Import in Datenbanksysteme vorbereitet werden können.
Hierbei setzen wir explizit &lt;strong>mehr&lt;/strong> auf nachvollziehbare Schritte und &lt;em>weniger&lt;/em> auf automatisierte, universell wiederverwendbare Code-Schnipsel.&lt;/p>
&lt;h2 id="generelles-vorgehen">Generelles Vorgehen&lt;/h2>
&lt;p>In diesem Tutorial extrahieren wir das Findbuch &amp;ldquo;&lt;em>Akten des Reichskammergerichts im Staatsarchiv Wertheim - Inventar des Bestands R J 10&lt;/em>&amp;rdquo; aus dem Anhang von &amp;ldquo;&lt;em>Band 57: Akten des Reichskammergerichts im Staatsarchiv Sigmaringen - Inventar des Bestands R 7. Bearb. von Raimund J. Weber. Kohlhammer 2004&lt;/em>&amp;rdquo;. Hierbei handelt es sich um 20 Findbucheinträge. Dies ist eine übersichtliche Anzahl für ein Tutorial. Wir haben die Techniken auch mit einem größeren Findbuch mit ca. 400 Einträgen getestet.&lt;/p>
&lt;p>Exemplarisch ist der erste Eintrag des Findbuchs in Abbildung 1 gezeigt.
Jeder Findbucheintrag ist in die folgenden acht nummerierten Abschnitte eingeteilt: (1) Bestellsignatur und Laufzeit, (2) Kläger, (3) Beklagter, (4) Prokuratoren, (5) Prozessart und Streitgegenstand, (6) Vorinstanzen, (7) Darinvermerk, (8) weitere Angaben. Einige dieser Abschnitte sind optional.
Bei dem ersten Eintrag fehlt zum Beispiel der Abschnitt 6 mit den Vorinstanzen.&lt;/p>
&lt;figure id="figure-erster-eintrag-aus-dem-findbuch-inventar-von-r-j-10">
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img alt="Erster Eintrag aus dem Findbuch Inventar von R J 10" srcset="
/post/2021-07-findbuecher-mit-openrefine-in-datenbank-uebernehmen/akten-rkg-band-57-wertheim-eintrag-01_hu3631d528038460c9540c3f22ba74a969_39007_207f7c9d40605f80b8bf04b0213e95aa.webp 400w,
/post/2021-07-findbuecher-mit-openrefine-in-datenbank-uebernehmen/akten-rkg-band-57-wertheim-eintrag-01_hu3631d528038460c9540c3f22ba74a969_39007_3d0e7c6af020298fccfebd1db4d33c14.webp 760w,
/post/2021-07-findbuecher-mit-openrefine-in-datenbank-uebernehmen/akten-rkg-band-57-wertheim-eintrag-01_hu3631d528038460c9540c3f22ba74a969_39007_1200x1200_fit_q75_h2_lanczos_3.webp 1200w"
src="https://fdmlab.landesarchiv-bw.de/post/2021-07-findbuecher-mit-openrefine-in-datenbank-uebernehmen/akten-rkg-band-57-wertheim-eintrag-01_hu3631d528038460c9540c3f22ba74a969_39007_207f7c9d40605f80b8bf04b0213e95aa.webp"
width="610"
height="467"
loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;figcaption data-pre="Abbildung&amp;nbsp;" data-post=":&amp;nbsp;" class="numbered">
Erster Eintrag aus dem Findbuch Inventar von R J 10
&lt;/figcaption>&lt;/figure>
&lt;p>Die einzelnen Abschnitte enthalten teilweise zusammenhängende Informationsbestandteile (Beklagte, Prokuratoren, Vorinstanzen, &amp;hellip;).
Teilweise enthalten sie jedoch auch mehrere Informationsbestandteile, wie zum Beispiel im ersten Abschnitt.&lt;/p>
&lt;blockquote>
&lt;div class="entities" style="line-height: 2.5; direction: ltr">1 &lt;mark class="entity" style="background: #b3e2cd; padding: 0.45em 0.6em; margin: 0 0.25em; line-height: 1; border-radius: 0.35em;"> 1 &lt;span style="font-size: 0.8em; font-weight: bold; line-height: 1; border-radius: 0.35em; vertical-align: middle; margin-left: 0.5rem">Nr&lt;/span> &lt;/mark> ( &lt;mark class="entity" style="background: #f4cae4; padding: 0.45em 0.6em; margin: 0 0.25em; line-height: 1; border-radius: 0.35em;"> C 2145 &lt;span style="font-size: 0.8em; font-weight: bold; line-height: 1; border-radius: 0.35em; vertical-align: middle; margin-left: 0.5rem">Altsignatur&lt;/span> &lt;/mark> ) &lt;mark class="entity" style="background: #e6f5c9; padding: 0.45em 0.6em; margin: 0 0.25em; line-height: 1; border-radius: 0.35em;"> 1597 – 1600 &lt;span style="font-size: 0.8em; font-weight: bold; line-height: 1; border-radius: 0.35em; vertical-align: middle; margin-left: 0.5rem">Laufzeit&lt;/span> &lt;/mark> &lt;br> Vorsignatur: &lt;mark class="entity" style="background: #cbd5e8; padding: 0.45em 0.6em; margin: 0 0.25em; line-height: 1; border-radius: 0.35em;"> R Rep. 9 Nr. 230 &lt;span style="font-size: 0.8em; font-weight: bold; line-height: 1; border-radius: 0.35em; vertical-align: middle; margin-left: 0.5rem">Vorsignatur&lt;/span> &lt;/mark> &lt;/div>
&lt;/blockquote>
&lt;p>Wir gehen bei der Extraktion in mehreren Schritten vor:&lt;/p>
&lt;ol>
&lt;li>Einträge des Inventars aus Findbuch extrahieren&lt;/li>
&lt;li>Einträge in Abschnitte aufteilen&lt;/li>
&lt;li>Einzelne Informationsbestandteile aus Abschnitten in Tabelle extrahieren&lt;/li>
&lt;li>Einzelne Informationsbestandteile aus Tabelle auf Datenbankschema übertragen&lt;/li>
&lt;/ol>
&lt;div class="mermaid">---
title: Datenextraktion Mapping
config:
look: handDrawn
theme: neutral
---
flowchart LR
subgraph findbuch[fas:fa-font Findbuch]
intro[Einführung]
Inventar
Index
end
subgraph abschnitte[far:fa-list-alt Abschnitte]
a1[Abschnitt 1]
a2[Abschnitt 2]
a3[Abschnitt 3]
a4[Abschnitt 4]
a5[Abschnitt 5]
a6[Abschnitt 6]
a7[Abschnitt 7]
a8[Abschnitt 8]
end
subgraph data[fas:fa-table Daten]
nr[Nr]
Altsignatur
Vorsignatur
Laufzeit
Klaeger[Kläger]
Beklagte
Prokuratoren
Prozessart
Gegenstand
Vorinstanzen
Darin
Umfang
Stapelhoehe[Stapelhöhe]
Hinweise
end
subgraph db[fas:fa-database Datenbank]
Titel
Bestellsignatur
Vorsignatur1[Vorsignatur 1]
Vorsignatur2[Vorsignatur 2]
Entstehungszeitraum[Entstehungszeitraum]
EntstehungszeitraumA[Entstehungszeitraum, Anm.]
db_Beklagte[Beklagte]
Bemerkung
db_Gegenstand[Gegenstand]
Enthaelt[Enthält]
db_Umfang[Umfang]
end
Inventar --> abschnitte
a1 --> nr &amp; Laufzeit &amp; Altsignatur &amp; Vorsignatur
a2 --> Klaeger
a3 --> Beklagte
a4 --> Prokuratoren
a5 --> Gegenstand &amp; Prozessart
a6 --> Vorinstanzen
a7 --> Darin
a8 --> Umfang &amp; Stapelhoehe &amp; Hinweise
Klaeger --> Titel
nr --> Bestellsignatur
Altsignatur --> Vorsignatur1
Vorsignatur --> Vorsignatur2
Laufzeit --> Entstehungszeitraum &amp; EntstehungszeitraumA
Beklagte --> db_Beklagte
Vorinstanzen &amp; Hinweise--> Bemerkung
Prozessart --> db_Gegenstand
Prokuratoren &amp; Gegenstand &amp; Darin--> Enthaelt
Umfang &amp; Stapelhoehe --> db_Umfang
&lt;/div>
&lt;p>&lt;strong>Zur Vollständigkeit&lt;/strong>: In anderen Findbüchern zu den Akten des Reichskammergerichtes im Landesarchiv BW gibt es noch weitere Informationen,
wie zum Beispiel eine separate Bestellsignatur, Schadensbeschreibungen, Literaturhinweise, Hinweise auf Abgabe der Akten an andere Institutionen, &amp;hellip;
Außerdem gibt es in unserem Erfassungsschema noch weitere Felder, die für alle Findbucheinträge mit einem festen Wert vorbelegt wurden.&lt;/p>
&lt;p>Diese Spezialbehandlungen ignorieren wir für dieses Tutorial.&lt;/p>
&lt;h3 id="technische-voraussetzungen">Technische Voraussetzungen&lt;/h3>
&lt;h4 id="openrefine">OpenRefine&lt;/h4>
&lt;p>Bei &lt;a href="https://openrefine.org/" target="_blank" rel="noopener">OpenRefine&lt;/a> handelt es sich um ein Excel ähnliches Werkzeug im Browser,
mit dem Daten in andere Formate überführt werden können.
Details zur Funktionsweise gibt es in der &lt;a href="https://docs.openrefine.org/" target="_blank" rel="noopener">Dokumentation von OpenRefine&lt;/a>
und in den &lt;a href="https://www.youtube.com/watch?v=B70J_H_zAWM&amp;amp;list=PL737054C67FCC0741" target="_blank" rel="noopener">Erklärvideos zu OpenRefine&lt;/a>.&lt;/p>
&lt;p>Wir verwenden das &lt;a href="https://openrefine.org/download.html" target="_blank" rel="noopener">Windows kit with embedded Java&lt;/a>,
mit dem wir ohne Administrationsrechte oder separater Java-Installation direkt loslegen können.&lt;/p>
&lt;div class="alert alert-note">
&lt;div>
Auch wenn die Arbeit mit OpenRefine im Browser stattfindet, so liegen die Daten trotzdem lokal auf der eigenen Festplatte.
Eine Datenübertragung findet dann statt, wenn zum Beispiel ein so genanntes
&lt;a href="https://docs.openrefine.org/manual/reconciling" target="_blank" rel="noopener">Reconciling&lt;/a> durchgeführt wird,
bei dem die Daten mit einem Dienst im Web abgeglichen werden.
&lt;/div>
&lt;/div>
&lt;h4 id="reguläre-ausdrücke">Reguläre Ausdrücke&lt;/h4>
&lt;figure id="figure-perl-problemshttpsxkcdcom1171-von-randall-munroe-unter-cc-by-nc-lizenzhttpcreativecommonsorglicensesby-nc25">
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img alt="[Perl Problems](https://xkcd.com/1171/) von Randall Munroe unter [CC BY-NC Lizenz](http://creativecommons.org/licenses/by-nc/2.5/)." srcset="
/post/2021-07-findbuecher-mit-openrefine-in-datenbank-uebernehmen/perl_problems_hu0e0484462f33f916343aead87d9b7933_20532_8fdf08fae82e8346817146df2a00337b.webp 400w,
/post/2021-07-findbuecher-mit-openrefine-in-datenbank-uebernehmen/perl_problems_hu0e0484462f33f916343aead87d9b7933_20532_df861a877b6fd6a5993e9f6618d9596b.webp 760w,
/post/2021-07-findbuecher-mit-openrefine-in-datenbank-uebernehmen/perl_problems_hu0e0484462f33f916343aead87d9b7933_20532_1200x1200_fit_q75_h2_lanczos_3.webp 1200w"
src="https://fdmlab.landesarchiv-bw.de/post/2021-07-findbuecher-mit-openrefine-in-datenbank-uebernehmen/perl_problems_hu0e0484462f33f916343aead87d9b7933_20532_8fdf08fae82e8346817146df2a00337b.webp"
width="548"
height="205"
loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;figcaption data-pre="Abbildung&amp;nbsp;" data-post=":&amp;nbsp;" class="numbered">
&lt;a href="https://xkcd.com/1171/" target="_blank" rel="noopener">Perl Problems&lt;/a> von Randall Munroe unter &lt;a href="http://creativecommons.org/licenses/by-nc/2.5/" target="_blank" rel="noopener">CC BY-NC Lizenz&lt;/a>.
&lt;/figcaption>&lt;/figure>
&lt;p>Bei Memes zu &lt;a href="https://de.wikipedia.org/wiki/Regul%C3%A4rer_Ausdruck" target="_blank" rel="noopener">regulären Ausdrücken&lt;/a> wird wie in Abbildung 2 häufig der Eindruck erweckt,
dass sie mehr Probleme erzeugen als sie tatsächlich lösen. Richtig dosiert sind sie jedoch ein hilfreiches Werkzeug bei der Datenextraktion.&lt;/p>
&lt;p>Zum Entwickeln, Testen und Verstehen von regulären Ausdrücken, nutzen wir &lt;a href="https://regex101.com/" target="_blank" rel="noopener">RegEx101&lt;/a> (Alternative: &lt;a href="https://regexr.com/" target="_blank" rel="noopener">RegExr&lt;/a>).
Hier bekommen wir wie in Abbildung 3 visuelles Feedback, auf welche Textzeilen unsere regulären Ausdrücke passen und was die einzelnen Bestandteile bedeuten.&lt;/p>
&lt;figure id="figure-bildschirmfoto-von-regex101httpsregex101com-mit-art-ecmascript-einem-regulären-ausdruck-zur-extraktion-der-altsignatur-in-der-mitte-oben-mehreren-beispielen-direkt-darunter-und-hilfreichen-informationen-auf-der-rechten-seite">
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img alt="Bildschirmfoto von [RegEx101](https://regex101.com/) mit Art *ECMAScript*, einem regulären Ausdruck zur Extraktion der **Altsignatur** in der Mitte oben, mehreren Beispielen direkt darunter und hilfreichen Informationen auf der rechten Seite." srcset="
/post/2021-07-findbuecher-mit-openrefine-in-datenbank-uebernehmen/regex101_hu03be89b75292a0eb807ee2f1e55d3728_80009_5450a57a227a11af8062f7f9afe0ef8a.webp 400w,
/post/2021-07-findbuecher-mit-openrefine-in-datenbank-uebernehmen/regex101_hu03be89b75292a0eb807ee2f1e55d3728_80009_7c368174fbd9183de9db61b29f1ee75f.webp 760w,
/post/2021-07-findbuecher-mit-openrefine-in-datenbank-uebernehmen/regex101_hu03be89b75292a0eb807ee2f1e55d3728_80009_1200x1200_fit_q75_h2_lanczos_3.webp 1200w"
src="https://fdmlab.landesarchiv-bw.de/post/2021-07-findbuecher-mit-openrefine-in-datenbank-uebernehmen/regex101_hu03be89b75292a0eb807ee2f1e55d3728_80009_5450a57a227a11af8062f7f9afe0ef8a.webp"
width="760"
height="421"
loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;figcaption data-pre="Abbildung&amp;nbsp;" data-post=":&amp;nbsp;" class="numbered">
Bildschirmfoto von &lt;a href="https://regex101.com/" target="_blank" rel="noopener">RegEx101&lt;/a> mit Art &lt;em>ECMAScript&lt;/em>, einem regulären Ausdruck zur Extraktion der &lt;strong>Altsignatur&lt;/strong> in der Mitte oben, mehreren Beispielen direkt darunter und hilfreichen Informationen auf der rechten Seite.
&lt;/figcaption>&lt;/figure>
&lt;h2 id="1-inventar-aus-findbuch-extrahieren">1. Inventar aus Findbuch extrahieren&lt;/h2>
&lt;p>OpenRefine ist für die Arbeit mit tabellenartigen Strukturen ausgelegt, weshalb es mühsam ist große Texte darin zu formatieren, bzw. längere Abschnitte zu löschen.
Daher empfiehlt es sich einige Vorbereitungen zu erledigen, &lt;strong>bevor&lt;/strong> die Daten in OpenRefine geladen werden.
Dazu gehört es zum Beispiel das Inventar in einer separaten Datei zu speichern und Abbildungen zu entfernen.
Außerdem sollten im Vorfeld ggf. Layout- und OCR-Fehler korrigiert werden.
Darauf gehen wir in einem separaten Artikel ein.&lt;/p>
&lt;p>In diesem Tutorial betrachten wir den Fall, dass wir auf Basis der originalen Word- oder PDF-Vorlage direkt eine &amp;ldquo;ordentliche&amp;rdquo; Textdatei erstellen können.&lt;/p>
&lt;blockquote>
&lt;p>💾 Wir stellen die aufgeräumte Datei zur Verfügung (Rechtsklick und &amp;ldquo;Ziel speichern unter&amp;hellip;&amp;rdquo;):&lt;/p>
&lt;/blockquote>
&lt;a href="https://fdmlab.landesarchiv-bw.de/data/rkg-57/akten-rkg-band-57-wertheim.txt" target="_blank">
&lt;i class="fas fa-file-alt pr-1 fa-fw">&lt;/i>Inventar Akten RKG Band 57 - Wertheim&lt;/a>
.
&lt;p>Wir möchten explizit dazu einladen diese Datei zu nutzen, um die einzelnen Schritte in OpenRefine selbst auszuprobieren und damit zu experimentieren.&lt;/p>
&lt;h2 id="2-einträge-in-abschnitte-aufteilen">2. Einträge in Abschnitte aufteilen&lt;/h2>
&lt;h3 id="findbuch-laden">Findbuch laden&lt;/h3>
&lt;p>Nachdem wir OpenRefine gestartet haben, öffnet sich die Bedienoberfläche im Webbrowser auf &lt;a href="http://localhost:3333" target="_blank" rel="noopener">http://localhost:3333&lt;/a> automatisch.&lt;/p>
&lt;p>Die Sprache der Oberfläche lässt sich auf Deutsch einstellen, wir bleiben jedoch bei Englisch.
Das macht es uns einfacher die einzelnen Bedienelemente und Funktionen mit der Dokumentation abzugleichen bzw. via Google Lösungen für Fragestellungen zu finden.&lt;/p>
&lt;p>Wie in Abbildung 4 gezeigt, laden wir unter &amp;ldquo;Create Project&amp;rdquo; die Textdatei aus dem letzten Abschnitt mit dem Inventar des Findbuchs in OpenRefine.&lt;/p>
&lt;figure id="figure-bildschirmfoto-vom-projekt-erstellen-formular-in-openrefine">
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img alt="Bildschirmfoto vom Projekt Erstellen Formular in OpenRefine." srcset="
/post/2021-07-findbuecher-mit-openrefine-in-datenbank-uebernehmen/openrefine-create-upload_hu12aab4d4757489fe8aa35bcf1061e7e7_27489_21a9f972ac1c8761ef7f10ce29009702.webp 400w,
/post/2021-07-findbuecher-mit-openrefine-in-datenbank-uebernehmen/openrefine-create-upload_hu12aab4d4757489fe8aa35bcf1061e7e7_27489_b65c02055023271202e2f8b02ae88886.webp 760w,
/post/2021-07-findbuecher-mit-openrefine-in-datenbank-uebernehmen/openrefine-create-upload_hu12aab4d4757489fe8aa35bcf1061e7e7_27489_1200x1200_fit_q75_h2_lanczos_3.webp 1200w"
src="https://fdmlab.landesarchiv-bw.de/post/2021-07-findbuecher-mit-openrefine-in-datenbank-uebernehmen/openrefine-create-upload_hu12aab4d4757489fe8aa35bcf1061e7e7_27489_21a9f972ac1c8761ef7f10ce29009702.webp"
width="760"
height="179"
loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;figcaption data-pre="Abbildung&amp;nbsp;" data-post=":&amp;nbsp;" class="numbered">
Bildschirmfoto vom Projekt Erstellen Formular in OpenRefine.
&lt;/figcaption>&lt;/figure>
&lt;p>Bei uns hat OpenRefine direkt die passenden Einstellungen für die Datei geladen.
Wir haben lediglich den Projektnamen angepasst und Schlagworte (Tags) vergeben. Um das neue Projekt zu erstellen, klicken Sie rechts oben auf den Button &amp;ldquo;Create Project&amp;rdquo;.
Manchmal möchte OpenRefine davon überzeugt werden, dass wir wirklich eine Textdatei ohne jegliche Tabellenstrukur laden möchten.
Dafür wie in Abbildung 5 unter &amp;ldquo;Parse data as&amp;rdquo; den Punkt &amp;ldquo;Line-based text files&amp;rdquo; auswählen.&lt;/p>
&lt;figure id="figure-bildschirmfoto-vom-projekt-einstellungsformular-in-openrefine">
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img alt="Bildschirmfoto vom Projekt Einstellungsformular in OpenRefine." srcset="
/post/2021-07-findbuecher-mit-openrefine-in-datenbank-uebernehmen/openrefine-create-settings_hud6e820b847deb165664e93c6831065b6_96205_f5012a0df3e28a705937901c27b46555.webp 400w,
/post/2021-07-findbuecher-mit-openrefine-in-datenbank-uebernehmen/openrefine-create-settings_hud6e820b847deb165664e93c6831065b6_96205_1f422eb078de0819cc8a16461b95c73f.webp 760w,
/post/2021-07-findbuecher-mit-openrefine-in-datenbank-uebernehmen/openrefine-create-settings_hud6e820b847deb165664e93c6831065b6_96205_1200x1200_fit_q75_h2_lanczos_3.webp 1200w"
src="https://fdmlab.landesarchiv-bw.de/post/2021-07-findbuecher-mit-openrefine-in-datenbank-uebernehmen/openrefine-create-settings_hud6e820b847deb165664e93c6831065b6_96205_f5012a0df3e28a705937901c27b46555.webp"
width="760"
height="370"
loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;figcaption data-pre="Abbildung&amp;nbsp;" data-post=":&amp;nbsp;" class="numbered">
Bildschirmfoto vom Projekt Einstellungsformular in OpenRefine.
&lt;/figcaption>&lt;/figure>
&lt;p>Wir haben für uns festgestellt, dass es einfacher ist initial die leeren Zeilen mitzuladen und später zu entfernen.
So helfen die leeren Zeilen zum Beispiel bei der visuellen Separierung der einzelnen Findbucheinträge.&lt;/p>
&lt;h3 id="vorbereitungen-in-openrefine">Vorbereitungen in OpenRefine&lt;/h3>
&lt;p>In OpenRefine haben wir nun jede einzelne Textzeile als &amp;ldquo;row&amp;rdquo;.
Um einen besseren Überblick zu haben benennen wir die (einzige) Spalte in &amp;ldquo;Original&amp;rdquo; um und stellen die Anzeige auf &amp;ldquo;50 rows&amp;rdquo; um.
Zum Umbenennen verwenden wir das Menüsymbol
&lt;i class="far fa-caret-square-down pr-1 fa-fw">&lt;/i> neben der Spaltenüberschrift und gehen in das Untermenü &amp;ldquo;Edit column&amp;quot;
&lt;i class="fas fa-caret-right pr-1 fa-fw">&lt;/i>&amp;quot;Rename this column&amp;rdquo;.&lt;/p>
&lt;p>Anschließend wollen wir die Kopfzeilen der ursprünglichen Seiten entfernen.
Diese sehen wie folgt aus (bei den Pfeilen handelt es sich um eine Repräsentation des Unicode Zeichens &lt;code>U+000C&lt;/code> für einen Seitenumbruch):&lt;/p>
&lt;pre>
&amp;#129145;486 Anhang
&amp;#129145; Inventar 487
&lt;/pre>
&lt;p>Um diese Zeilen zu entfernen klicken wir auf das Menü-Symbol
&lt;i class="far fa-caret-square-down pr-1 fa-fw">&lt;/i> in der Spalte Original und wählen den &amp;ldquo;Textfilter&amp;rdquo;.
Dort aktivieren wir das Auswahlkästchen
&lt;i class="far fa-check-square pr-1 fa-fw">&lt;/i> bei &amp;ldquo;regular expression&amp;rdquo; (siehe Abbildung 6).&lt;/p>
&lt;p>Durch ausprobieren entweder mit &lt;a href="https://regex101.com/" target="_blank" rel="noopener">RegEx101&lt;/a> oder direkt in dem Feld finden wir heraus, dass der reguläre Ausdruck &lt;code>\d\s+Anhang&lt;/code> (Zahl, viele Trennzeichen und das Wort Anhang) alle Zeilen filtert, die wir für die Filterung auf die ursprünglich &amp;ldquo;linken Seiten&amp;rdquo; benötigen.
Ein etwas aufwendigerer regulärer Ausdruck wäre &lt;code>\d{3,}\s{4,}Anhang$&lt;/code> (drei oder mehr Zahlen, vier oder mehr Leerzeichen und das Wort &amp;ldquo;Anhang&amp;rdquo; am Ende der Zeile).&lt;/p>
&lt;figure id="figure-bildschirmfoto-vom-textfilter-für-kopfzeilen-linker-seiten-in-openrefine">
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img alt="Bildschirmfoto vom Textfilter für Kopfzeilen linker Seiten in OpenRefine." srcset="
/post/2021-07-findbuecher-mit-openrefine-in-datenbank-uebernehmen/openrefine-textfilter_hu5f1c2d706604f78d6a33cb46fdb586e2_32553_6c4dee2f7f5fdeabfcb424d39d296f0b.webp 400w,
/post/2021-07-findbuecher-mit-openrefine-in-datenbank-uebernehmen/openrefine-textfilter_hu5f1c2d706604f78d6a33cb46fdb586e2_32553_bfdd0a751b634d44299a3fc9f5f9e8b8.webp 760w,
/post/2021-07-findbuecher-mit-openrefine-in-datenbank-uebernehmen/openrefine-textfilter_hu5f1c2d706604f78d6a33cb46fdb586e2_32553_1200x1200_fit_q75_h2_lanczos_3.webp 1200w"
src="https://fdmlab.landesarchiv-bw.de/post/2021-07-findbuecher-mit-openrefine-in-datenbank-uebernehmen/openrefine-textfilter_hu5f1c2d706604f78d6a33cb46fdb586e2_32553_6c4dee2f7f5fdeabfcb424d39d296f0b.webp"
width="669"
height="313"
loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;figcaption data-pre="Abbildung&amp;nbsp;" data-post=":&amp;nbsp;" class="numbered">
Bildschirmfoto vom Textfilter für Kopfzeilen linker Seiten in OpenRefine.
&lt;/figcaption>&lt;/figure>
&lt;p>Über das Menü-Symbol
&lt;i class="far fa-caret-square-down pr-1 fa-fw">&lt;/i> neben der Spalte &amp;ldquo;All&amp;rdquo; können wir diese Zeilen im Untermenü &amp;ldquo;Edit rows&amp;quot;
&lt;i class="fas fa-caret-right pr-1 fa-fw">&lt;/i>&amp;quot;Remove matching rows&amp;rdquo; entfernen.&lt;/p>
&lt;p>Die Kopfzeilen für die ursprünglich rechten Seiten können via &lt;code>Inventar\s+\d&lt;/code> bzw. &lt;code>Inventar\s{4,}\d{3,}$&lt;/code> identifiziert und entfernt werden.&lt;/p>
&lt;div class="alert alert-note">
&lt;div>
In diesem Findbuch hätten wir auch lediglich nach &amp;ldquo;Anhang&amp;rdquo; und &amp;ldquo;Inventar&amp;rdquo; suchen können um die einzelnen Zeilen zu identifizieren.
Teilweise werden diese Wörter aber auch in den Texten der Findbucheinträge verwendet und wir wollten daher gleich den generischen Ansatz vorstellen.
&lt;/div>
&lt;/div>
&lt;p>Über das Schließen-Symbol
&lt;i class="far fa-window-close pr-1 fa-fw">&lt;/i> am Textfilter kommen wir zur ursprünglichen Ansicht zurück.&lt;/p>
&lt;h3 id="findbuchnummer-extrahieren">Findbuchnummer extrahieren&lt;/h3>
&lt;h4 id="neue-spalte-anlegen">Neue Spalte anlegen&lt;/h4>
&lt;p>Als erstes Feld extrahieren wir die Findbuchnummer aus den Textzeilen.
Dafür verwenden wir &amp;ldquo;Original&amp;quot;
&lt;i class="far fa-caret-square-down pr-1 fa-fw">&lt;/i>&amp;quot;Edit column&amp;quot;
&lt;i class="fas fa-caret-right pr-1 fa-fw">&lt;/i>&amp;quot;Add column based on this column&amp;hellip;&amp;rdquo;.&lt;/p>
&lt;p>Wir verwenden die von &lt;a href="https://docs.openrefine.org/manual/expressions" target="_blank" rel="noopener">GREL&lt;/a> unterstützten regulären Ausdrücke.
Um die Findbuchnummer zu extrahieren, verwenden wir &lt;a href="https://docs.openrefine.org/manual/grelfunctions#matchs-p" target="_blank" rel="noopener">match&lt;/a> auf jeder Zeile (&lt;code>value&lt;/code>, siehe Abbildung 7).&lt;/p>
&lt;figure id="figure-bildschirmfoto-des-dialogs-zum-hinzufügen-der-spalte-nr-für-die-findbuchnummer-in-openrefine">
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img alt="Bildschirmfoto des Dialogs zum Hinzufügen der Spalte Nr für die Findbuchnummer in OpenRefine." srcset="
/post/2021-07-findbuecher-mit-openrefine-in-datenbank-uebernehmen/openrefine-column-nr_huc6724e6eb74bd78c5eb8b5eaebc05e1f_30407_24107f127b76a96344497a4395e3824c.webp 400w,
/post/2021-07-findbuecher-mit-openrefine-in-datenbank-uebernehmen/openrefine-column-nr_huc6724e6eb74bd78c5eb8b5eaebc05e1f_30407_40d27736e51cc14cde62687e17078521.webp 760w,
/post/2021-07-findbuecher-mit-openrefine-in-datenbank-uebernehmen/openrefine-column-nr_huc6724e6eb74bd78c5eb8b5eaebc05e1f_30407_1200x1200_fit_q75_h2_lanczos_3.webp 1200w"
src="https://fdmlab.landesarchiv-bw.de/post/2021-07-findbuecher-mit-openrefine-in-datenbank-uebernehmen/openrefine-column-nr_huc6724e6eb74bd78c5eb8b5eaebc05e1f_30407_24107f127b76a96344497a4395e3824c.webp"
width="722"
height="528"
loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;figcaption data-pre="Abbildung&amp;nbsp;" data-post=":&amp;nbsp;" class="numbered">
Bildschirmfoto des Dialogs zum Hinzufügen der Spalte Nr für die Findbuchnummer in OpenRefine.
&lt;/figcaption>&lt;/figure>
&lt;p>Die verwendete &amp;ldquo;Expression&amp;rdquo; filtert Zeilen, die mit 1 und mehreren Leerzeichen beginnen und extrahiert alles direkt nach den Leerzeichen, was &lt;strong>keine&lt;/strong> Klammer ist.
Das anschließende &lt;code>.+&lt;/code> benötigen wir, da der reguläre Ausdruck bei &lt;a href="https://docs.openrefine.org/manual/grelfunctions#matchs-p" target="_blank" rel="noopener">match&lt;/a>, anders als bei &lt;a href="https://docs.openrefine.org/manual/grelfunctions#finds-sub-or-p" target="_blank" rel="noopener">find&lt;/a>, auf die komplette Zeile passen muss.
Von der Liste (technisch &lt;a href="https://docs.openrefine.org/manual/grelfunctions#array-functions" target="_blank" rel="noopener">Array&lt;/a>) der möglichen Ergebnisse wählen wir das erste Ergebnis via &lt;code>[0]&lt;/code> und entfernen überflüssige Leerzeichen mit &lt;a href="https://docs.openrefine.org/manual/grelfunctions#trims" target="_blank" rel="noopener">trim&lt;/a>.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="nx">value&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">match&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sr">/1\s+([^(]+).+/&lt;/span>&lt;span class="p">)[&lt;/span>&lt;span class="mi">0&lt;/span>&lt;span class="p">].&lt;/span>&lt;span class="nx">trim&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h4 id="unterschied-zwischen-rows-und-records">Unterschied zwischen rows und records&lt;/h4>
&lt;p>Die Spalte Nr verschieben wir anschließend ganz an den Anfang via &amp;ldquo;Nr&amp;quot;
&lt;i class="far fa-caret-square-down pr-1 fa-fw">&lt;/i>&amp;quot;Edit column&amp;quot;
&lt;i class="fas fa-caret-right pr-1 fa-fw">&lt;/i>&amp;quot;Move column to beginning&amp;rdquo;.
Das hat zur Folge, dass wir nun zwischen &amp;ldquo;rows&amp;rdquo; und &amp;ldquo;records&amp;rdquo; hin- und herwechseln können.
OpenRefine gruppiert die Zeilen anhand der Merkmale in der ersten Spalte in so genannte &amp;ldquo;records&amp;rdquo;.&lt;/p>
&lt;p>Anstatt der erwarteten 20 Findbucheinträge haben wir jedoch 71?&lt;/p>
&lt;p>Also überprüfen wir, ob bei der Extraktion der Findbuchnummern etwas schief gelaufen ist.&lt;/p>
&lt;h4 id="extraktion-überprüfen">Extraktion überprüfen&lt;/h4>
&lt;p>Um die Extraktion zu überprüfen ohne uns durch alle Seiten zu klicken, verwenden wir ein &amp;ldquo;&lt;a href="https://docs.openrefine.org/manual/facets" target="_blank" rel="noopener">Facet&lt;/a>&amp;rdquo; um die entsprechenden Zeilen zu filtern.
Dafür verwenden wir &amp;ldquo;Nr&amp;quot;
&lt;i class="far fa-caret-square-down pr-1 fa-fw">&lt;/i>&amp;quot;Facet&amp;quot;
&lt;i class="fas fa-caret-right pr-1 fa-fw">&lt;/i>&amp;quot;Text facet&amp;rdquo;.
In dem &amp;ldquo;Facet&amp;rdquo; wählen wir &amp;ldquo;blank&amp;rdquo; und invertieren die Auswahl oben im &amp;ldquo;Facet&amp;rdquo; über &amp;ldquo;invert&amp;rdquo; (siehe ABbildung 8).&lt;/p>
&lt;figure id="figure-bildschirmfoto-des-facet-für-die-spalte-nr-in-openrefine">
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img alt="Bildschirmfoto des Facet für die Spalte Nr in OpenRefine." srcset="
/post/2021-07-findbuecher-mit-openrefine-in-datenbank-uebernehmen/openrefine-column-nr-facet_hu3d63954ff3ca2a9fcf1a63fe26ca4812_65934_f5a207d0ae0053e08324b2087ef5959d.webp 400w,
/post/2021-07-findbuecher-mit-openrefine-in-datenbank-uebernehmen/openrefine-column-nr-facet_hu3d63954ff3ca2a9fcf1a63fe26ca4812_65934_c13859750640dcd9d68fd1cbcbad9fac.webp 760w,
/post/2021-07-findbuecher-mit-openrefine-in-datenbank-uebernehmen/openrefine-column-nr-facet_hu3d63954ff3ca2a9fcf1a63fe26ca4812_65934_1200x1200_fit_q75_h2_lanczos_3.webp 1200w"
src="https://fdmlab.landesarchiv-bw.de/post/2021-07-findbuecher-mit-openrefine-in-datenbank-uebernehmen/openrefine-column-nr-facet_hu3d63954ff3ca2a9fcf1a63fe26ca4812_65934_f5a207d0ae0053e08324b2087ef5959d.webp"
width="760"
height="561"
loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;figcaption data-pre="Abbildung&amp;nbsp;" data-post=":&amp;nbsp;" class="numbered">
Bildschirmfoto des Facet für die Spalte Nr in OpenRefine.
&lt;/figcaption>&lt;/figure>
&lt;p>Die Extraktion scheint funktioniert zu haben. Beim genaueren Betrachten der &amp;ldquo;records&amp;rdquo; fällt jedoch auf, dass Leerzeilen ebenfalls als &amp;ldquo;records&amp;rdquo; gezählt werden.&lt;/p>
&lt;h4 id="leerzeilen-entfernen">Leerzeilen entfernen&lt;/h4>
&lt;p>Es ist also an der Zeit die Leerzeilen zu entfernen. Dafür wechseln wir wieder in die Ansicht &amp;ldquo;rows&amp;rdquo; und erstellen ein &amp;ldquo;Facet&amp;rdquo; via
&amp;ldquo;All&amp;quot;
&lt;i class="far fa-caret-square-down pr-1 fa-fw">&lt;/i>&amp;quot;Facet&amp;quot;
&lt;i class="fas fa-caret-right pr-1 fa-fw">&lt;/i>&amp;quot;Facet by blank (null or empty string)&amp;rdquo;.
Im &amp;ldquo;Facet&amp;rdquo; wählen wir anschließend &amp;ldquo;true&amp;rdquo; und löschen die ausgewählten Zeilen via &amp;ldquo;All&amp;quot;
&lt;i class="far fa-caret-square-down pr-1 fa-fw">&lt;/i>&amp;quot;Edit rows&amp;quot;
&lt;i class="fas fa-caret-right pr-1 fa-fw">&lt;/i>&amp;quot;Remove matching rows&amp;rdquo;.&lt;/p>
&lt;p>Wenn wir das &amp;ldquo;Facet&amp;rdquo; wieder schließen und nun in die &amp;ldquo;records&amp;rdquo; Ansicht wechseln, haben wir genau 20 Einträge.&lt;/p>
&lt;div class="alert alert-note">
&lt;div>
Hier sollte sich spätestens das Bedürfnis melden diesen Zwischenstand speichern zu wollen.
Das ist nicht notwendig, da OpenRefine alle Schritte (die Veränderungen einführen) speichert und unter &amp;ldquo;&lt;a href="https://docs.openrefine.org/manual/running#history-undoredo" target="_blank" rel="noopener">Undo/Redo&lt;/a>&amp;rdquo; zur Verfügung stellt.
&lt;/div>
&lt;/div>
&lt;h3 id="abschnittnummer-extrahieren">Abschnittnummer extrahieren&lt;/h3>
&lt;p>Die Abschnittnummer benötigen wir zwar nicht für unsere Datenbank, sie hilft uns aber die einzelnen Abschnitte mit OpenRefine zu gruppieren und zu bearbeiten.&lt;/p>
&lt;p>Analog zur Extraktion der Findbuch Nummer fügen wir eine neue Spalte Abschnitt hinzu (&amp;ldquo;Original&amp;quot;
&lt;i class="far fa-caret-square-down pr-1 fa-fw">&lt;/i>&amp;quot;Edit column&amp;quot;
&lt;i class="fas fa-caret-right pr-1 fa-fw">&lt;/i>&amp;quot;Add column based on this column&amp;hellip;&amp;rdquo;) und verwenden die folgende &amp;ldquo;Expression&amp;rdquo;:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="nx">value&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">match&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sr">/([1-8])\s\s.+/&lt;/span>&lt;span class="p">)[&lt;/span>&lt;span class="mi">0&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Diese Expression filtert Zeilen, die einer Zahl zwischen 1 und 8 gefolgt von zwei Leerzeichen beginnen, und extrahiert anschließend die Zahl.&lt;/p>
&lt;p>Die neue Spalte verschieben wir anschließend an den Anfang (&amp;ldquo;Abschnitt&amp;quot;
&lt;i class="far fa-caret-square-down pr-1 fa-fw">&lt;/i>&amp;quot;Edit column&amp;quot;
&lt;i class="fas fa-caret-right pr-1 fa-fw">&lt;/i>&amp;quot;Move column to beginning&amp;rdquo;) und kontrollieren die extrahierten Bestandteile (&amp;ldquo;Abschnitt&amp;quot;
&lt;i class="far fa-caret-square-down pr-1 fa-fw">&lt;/i>&amp;quot;Facet&amp;quot;
&lt;i class="fas fa-caret-right pr-1 fa-fw">&lt;/i>&amp;quot;Text facet&amp;rdquo;). Das &amp;ldquo;Facet&amp;rdquo; auf den Abschnittsnummern lassen wir stehen, da wir es später noch benötigen werden.&lt;/p>
&lt;h4 id="zeilen-der-abschnitte-zusammenfassen">Zeilen der Abschnitte zusammenfassen&lt;/h4>
&lt;p>Das Verschieben der Spalte Abschnitt an den Anfang sorgt dafür, dass jeder Abschnitt nun einen eigenen &amp;ldquo;record&amp;rdquo; darstellt.&lt;/p>
&lt;p>Das ist von daher von Vorteil, da wir alle Zeilen eines &amp;ldquo;records&amp;rdquo; in eine Zeile zusammenfassen können.
Dafür verwenden wir &amp;ldquo;Original&amp;quot;
&lt;i class="far fa-caret-square-down pr-1 fa-fw">&lt;/i>&amp;quot;Edit cells&amp;quot;
&lt;i class="fas fa-caret-right pr-1 fa-fw">&lt;/i>&amp;quot;Join multi-valued cells&amp;hellip;&amp;rdquo;
und geben &lt;code>-:::-&lt;/code> als Trennsequenz (&amp;ldquo;separator&amp;rdquo;) an. Diese Zeichenfolge verwenden wir, da wir sie anschließend mit einem Zeilenumbruch &lt;code>\n&lt;/code> ersetzen wollen.
Ein direktes Verbinden von Zellen mit einem Zeilenumbruch geht in der aktuellen Version (3.5.1) nicht.&lt;/p>
&lt;p>Via &amp;ldquo;Original&amp;quot;
&lt;i class="far fa-caret-square-down pr-1 fa-fw">&lt;/i>&amp;quot;Edit cells&amp;quot;
&lt;i class="fas fa-caret-right pr-1 fa-fw">&lt;/i>&amp;quot;Transform&amp;hellip;&amp;rdquo; ersetzen wir unsere spezifische Trennsequenz anschließend durch einen Zeilenumbruch.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="nx">value&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">replace&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;-:::-&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;\n&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Wie in Abbildung 9 gezeigt, haben wir nun gleich viele Zeilen (&amp;ldquo;rows&amp;rdquo;) wie &amp;ldquo;records&amp;rdquo;.&lt;/p>
&lt;figure id="figure-bildschirmfoto-der-zwei-extrahierten-spalten-abschnitt-und-nr-in-openrefine">
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img alt="Bildschirmfoto der zwei extrahierten Spalten Abschnitt und Nr in OpenRefine." srcset="
/post/2021-07-findbuecher-mit-openrefine-in-datenbank-uebernehmen/openrefine-column-abschnitt_huca81e1c249d03303b5315c7869e4d391_61337_4b2ea7a1d2edf4a3ed1175dd1baf5f99.webp 400w,
/post/2021-07-findbuecher-mit-openrefine-in-datenbank-uebernehmen/openrefine-column-abschnitt_huca81e1c249d03303b5315c7869e4d391_61337_fe1cfe181a367997e1bfa0edf1e8d4df.webp 760w,
/post/2021-07-findbuecher-mit-openrefine-in-datenbank-uebernehmen/openrefine-column-abschnitt_huca81e1c249d03303b5315c7869e4d391_61337_1200x1200_fit_q75_h2_lanczos_3.webp 1200w"
src="https://fdmlab.landesarchiv-bw.de/post/2021-07-findbuecher-mit-openrefine-in-datenbank-uebernehmen/openrefine-column-abschnitt_huca81e1c249d03303b5315c7869e4d391_61337_4b2ea7a1d2edf4a3ed1175dd1baf5f99.webp"
width="760"
height="437"
loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;figcaption data-pre="Abbildung&amp;nbsp;" data-post=":&amp;nbsp;" class="numbered">
Bildschirmfoto der zwei extrahierten Spalten Abschnitt und Nr in OpenRefine.
&lt;/figcaption>&lt;/figure>
&lt;h2 id="3-findbuch-inventar-in-tabelle-umwandeln">3. Findbuch Inventar in Tabelle umwandeln&lt;/h2>
&lt;p>Nun können wir den Text Abschnitt für Abschnitt in ein tabellenartiges Format überführen.
Das Vorgehen ist prinzipiell immer gleich:&lt;/p>
&lt;ol>
&lt;li>Mit einer &amp;ldquo;Expression&amp;rdquo; eine neue Spalte basierend auf der Spalte Original hinzufügen.&lt;/li>
&lt;li>Eventuell Zeilenumbrüche in der neuen Spalte entfernen.&lt;/li>
&lt;/ol>
&lt;h3 id="abschnitt-1-nr-altsignatur-vorsignatur-laufzeit">Abschnitt 1 (Nr, Altsignatur, Vorsignatur, Laufzeit)&lt;/h3>
&lt;p>In dem &amp;ldquo;Facet&amp;rdquo; für den Abschnitt wählen wir den Abschnitt 1.&lt;/p>
&lt;p>Die Spalte Nr&amp;quot; haben wir bereits in einem der vorbereitenden Schritte extrahiert.
Es folgen die Expressions für die restlichen drei Angaben, die sich noch in Abschnitt 1 befinden, nämlich Altsignatur, Vorsignatur und Laufzeit.
Hinzugefügt wird mit &amp;ldquo;Original&amp;quot;
&lt;i class="far fa-caret-square-down pr-1 fa-fw">&lt;/i>&amp;quot;Edit column&amp;quot;
&lt;i class="fas fa-caret-right pr-1 fa-fw">&lt;/i>&amp;quot;Add column based on this column&amp;hellip;&amp;rdquo;.&lt;/p>
&lt;blockquote>
&lt;div class="entities" style="line-height: 2.5; direction: ltr">1 &lt;mark class="entity" style="background: #b3e2cd; padding: 0.45em 0.6em; margin: 0 0.25em; line-height: 1; border-radius: 0.35em;"> 1 &lt;span style="font-size: 0.8em; font-weight: bold; line-height: 1; border-radius: 0.35em; vertical-align: middle; margin-left: 0.5rem">Nr&lt;/span> &lt;/mark> ( &lt;mark class="entity" style="background: #f4cae4; padding: 0.45em 0.6em; margin: 0 0.25em; line-height: 1; border-radius: 0.35em;"> C 2145 &lt;span style="font-size: 0.8em; font-weight: bold; line-height: 1; border-radius: 0.35em; vertical-align: middle; margin-left: 0.5rem">Altsignatur&lt;/span> &lt;/mark> ) &lt;mark class="entity" style="background: #e6f5c9; padding: 0.45em 0.6em; margin: 0 0.25em; line-height: 1; border-radius: 0.35em;"> 1597 – 1600 &lt;span style="font-size: 0.8em; font-weight: bold; line-height: 1; border-radius: 0.35em; vertical-align: middle; margin-left: 0.5rem">Laufzeit&lt;/span> &lt;/mark> &lt;br> Vorsignatur: &lt;mark class="entity" style="background: #cbd5e8; padding: 0.45em 0.6em; margin: 0 0.25em; line-height: 1; border-radius: 0.35em;"> R Rep. 9 Nr. 230 &lt;span style="font-size: 0.8em; font-weight: bold; line-height: 1; border-radius: 0.35em; vertical-align: middle; margin-left: 0.5rem">Vorsignatur&lt;/span> &lt;/mark> &lt;/div>
&lt;/blockquote>
&lt;h4 id="altsignatur">Altsignatur&lt;/h4>
&lt;p>Die Altsignatur steht in Klammern direkt nach der Findbuchnummer.
Anstatt mit &lt;code>match&lt;/code> einen regulären Ausdruck für die komplette Zeile zu definieren, verwenden wir nun &lt;code>find&lt;/code>.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="nx">value&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">find&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sr">/(?&amp;lt;=\().+?(?=\))/&lt;/span>&lt;span class="p">)[&lt;/span>&lt;span class="mi">0&lt;/span>&lt;span class="p">].&lt;/span>&lt;span class="nx">trim&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Wir suchen eine beliebige Folge von Zeichen, die zwischen zwei Klammern steht. Dafür nutzen wir so genannte &amp;ldquo;Look-around assertions&amp;rdquo;.
Anschließend wählen wir das erste Ergebnis aus und entfernen vorsichtshalber noch Leerzeichen am Anfang und am Ende.&lt;/p>
&lt;p>Alternativ können wir die Klammern auch mit in den regulären Ausdruck aufnehmen und anschließend mit &lt;a href="https://docs.openrefine.org/manual/grelfunctions#substrings-n-from-n-to-optional" target="_blank" rel="noopener">substring&lt;/a> entfernen.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="nx">value&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">find&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sr">/\([^)]+\)/&lt;/span>&lt;span class="p">)[&lt;/span>&lt;span class="mi">0&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">.&lt;/span>&lt;span class="nx">substring&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">1&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="o">-&lt;/span>&lt;span class="mi">1&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">.&lt;/span>&lt;span class="nx">trim&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h4 id="vorsignatur">Vorsignatur&lt;/h4>
&lt;p>Die Vorsignatur steht direkt hinter dem Text &amp;ldquo;Vorsignatur:&amp;rdquo;.
Dafür können wir eine &amp;ldquo;positive look-behind assertion&amp;rdquo; verwenden.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="nx">value&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">find&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sr">/(?&amp;lt;=Vorsignatur:).+/&lt;/span>&lt;span class="p">)[&lt;/span>&lt;span class="mi">0&lt;/span>&lt;span class="p">].&lt;/span>&lt;span class="nx">trim&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Alternativ kann auch hier der Text &amp;ldquo;Vorsignatur:&amp;rdquo; mit in den regulären Ausdruck aufgenommen und anschließend mit &lt;a href="https://docs.openrefine.org/manual/grelfunctions#replaces-s-or-p-find-s-replace" target="_blank" rel="noopener">replace&lt;/a> entfernt werden.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="nx">value&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">find&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sr">/Vorsignatur: .+/&lt;/span>&lt;span class="p">)[&lt;/span>&lt;span class="mi">0&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">.&lt;/span>&lt;span class="nx">replace&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;Vorsignatur:&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">.&lt;/span>&lt;span class="nx">trim&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Das setzt jedoch voraus, dass der Text &amp;ldquo;Vorsignatur:&amp;rdquo; auch einheitlich geschrieben wurde.
Die Variante mit der &amp;ldquo;positive look-behind assertion&amp;rdquo; kann bei unterschiedlichen Schreibweisen einfacher angepasst werden.&lt;/p>
&lt;h4 id="laufzeit">Laufzeit&lt;/h4>
&lt;p>Die Laufzeit steht mit Abstand hinter der eingeklammerten Altsignatur.
Also können wir hier als &amp;ldquo;positive look-behind&amp;rdquo; nach einer schließenden Klammer, gefolgt von mehreren Leerzeichen suchen, und alle folgenden Zeichen als Laufzeit extrahieren.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="nx">value&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">find&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sr">/(?&amp;lt;=\)\s{4}).+/&lt;/span>&lt;span class="p">)[&lt;/span>&lt;span class="mi">0&lt;/span>&lt;span class="p">].&lt;/span>&lt;span class="nx">trim&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Alternativ können wir auch hier die Klammer mit in den regulären Ausdruck aufnehmen und sie anschließend entfernen.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="nx">value&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">find&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sr">/\)\s{4,}.+/&lt;/span>&lt;span class="p">)[&lt;/span>&lt;span class="mi">0&lt;/span>&lt;span class="p">].&lt;/span>&lt;span class="nx">substring&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">1&lt;/span>&lt;span class="p">).&lt;/span>&lt;span class="nx">trim&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="abschnitt-2-kläger">Abschnitt 2 (Kläger)&lt;/h3>
&lt;p>Wir wechseln mit dem &amp;ldquo;Facet&amp;rdquo; zu Abschnitt 2 und übernehmen hier den kompletten Inhalt, den wir anschließend bearbeiten.
Wir entfernen die Abschnittnummer am Anfang und das Trennzeichen &lt;code>. /.&lt;/code> zwischen Käger und Beklagten.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="nx">value&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">replace&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sr">/^2\s{2,}/&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">.&lt;/span>&lt;span class="nx">replace&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sr">/\n\s*\.\s*\/\./&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">.&lt;/span>&lt;span class="nx">trim&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Ab einer bestimmten Menge an Findbucheinträgen gibt es hin- und wieder Unterschiede in der Anzahl der Leerzeichen (Tippfehler, Scanfehler, &amp;hellip;), weshalb wir diese dynamisch mit regulären Ausdrücken beschrieben haben. Alternativ hätten wir in diesem Findbuch auch ohne reguläre Ausdrücke arbeiten können.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="nx">value&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">replace&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;2 &amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">.&lt;/span>&lt;span class="nx">replace&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;. /.&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">.&lt;/span>&lt;span class="nx">trim&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Es ist hier auch möglich den Text zu Verkürzen, anstatt die 2 zu ersetzen:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="nx">value&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">substring&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">1&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">.&lt;/span>&lt;span class="nx">replace&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;. /.&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">.&lt;/span>&lt;span class="nx">trim&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;div class="alert alert-note">
&lt;div>
Wir zeigen hier bewusst Lösungen mit unterschiedlicher Komplexität.
Je nach vorliegendem Datenmaterial sind die einfachen Strategien (Textverkürzung, Textersetzung, &amp;hellip;) vollkommen ausreichend.
Teilweise sind Findbücher jedoch inkonsistent (unterschiedliche Autoren, unterschiedliche Archivalien, Tippfehler, Scanfehler, &amp;hellip;).
Hier benötigt es komplexere Lösungen, wie zum Beispiel reguläre Ausdrücke.
&lt;/div>
&lt;/div>
&lt;h4 id="zeilenumbrüche-entfernen">Zeilenumbrüche entfernen&lt;/h4>
&lt;p>Bei den Klägern wollen wir zusätzlich die Leerzeilen entfernen.
Dafür gehen wir auf &amp;ldquo;Kläger&amp;quot;
&lt;i class="far fa-caret-square-down pr-1 fa-fw">&lt;/i>&amp;quot;Edit cells&amp;quot;
&lt;i class="fas fa-caret-right pr-1 fa-fw">&lt;/i>&amp;quot;Transform&amp;hellip;&amp;rdquo;
und verwenden die folgende Expression:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="nx">value&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">replace&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sr">/-\n\s*(?![A-Z])/&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">.&lt;/span>&lt;span class="nx">replace&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sr">/(?&amp;lt;=-)\n\s*(?=[A-Z])/&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">.&lt;/span>&lt;span class="nx">replace&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sr">/\n\s*/&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34; &amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Dieser Expression entfernt zuerst Zeilenumbrüche (mit Bindestrich), die mit einem Bindestrich enden, wobei das erste Wort in der nächsten Zeile nicht groß geschrieben sein darf.
Dann werden Zeilenumbrüche entfernt, bei denen der Bindestrich erhalten bleiben soll.
Anschließend werden die restlichen Zeilenumbrüche mit einem Leerzeichen ersetzt.
Diese Umwandlung können wir wie beschrieben in einem nachgelagerten Schritt, oder direkt bei der Erstellung der Spalte durchführen.&lt;/p>
&lt;h3 id="abschnitt-3-beklagte">Abschnitt 3 (Beklagte)&lt;/h3>
&lt;p>Wir wechseln mit dem “Facet” zu Abschnitt 3, übernehmen hier den kompletten Inhalt, entfernen die Abschnittnummer, und entfernen die Zeilenumbrüche.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="nx">value&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">replace&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sr">/^3\s{2,}/&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">.&lt;/span>&lt;span class="nx">trim&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">.&lt;/span>&lt;span class="nx">replace&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sr">/-\n\s*(?![A-Z])/&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">.&lt;/span>&lt;span class="nx">replace&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sr">/(?&amp;lt;=-)\n\s*(?=[A-Z])/&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">.&lt;/span>&lt;span class="nx">replace&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sr">/\n\s*/&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34; &amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="abschnitt-4-prokuratoren">Abschnitt 4 (Prokuratoren)&lt;/h3>
&lt;p>Wir wechseln mit dem “Facet” zu Abschnitt 4 und übernehmen hier den kompletten Inhalt. Die Formatierung (Zeilenumbrüche, &amp;hellip;) wollen wir hier beibehalten.
Lediglich die Abschnittnummer entfernen wir.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="nx">value&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">replace&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sr">/^4/&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34; &amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="abschnitt-5-prozessart-und-gegenstand">Abschnitt 5 (Prozessart und Gegenstand)&lt;/h3>
&lt;p>Wir wechseln mit dem “Facet” zu Abschnitt 5. Hier wollen wir die Prozessart von dem Prozessgegenstand trennen.
Hierfür ist es in den meisten Fällen ausreichend, die erste Zeile von den restlichen zu trennen.
Bei manchen Prozessen erstreckt sich die Prozessart jedoch auf mehrere Zeilen.
Es ist zwar möglich auf Grund verschiedener Merkmale die Anzahl der Zeilen für die Prozessart zu bestimmen, der Algorithmus dafür wird jedoch komplex.
Daher prüfen wir die einzelnen Einträge und korrigieren bei den Ausnahmen manuell nach.&lt;/p>
&lt;h4 id="prozessart">Prozessart&lt;/h4>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="nx">value&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">split&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;\n&amp;#34;&lt;/span>&lt;span class="p">)[&lt;/span>&lt;span class="mi">0&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">.&lt;/span>&lt;span class="nx">replace&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sr">/^5\s{2,}/&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">.&lt;/span>&lt;span class="nx">trim&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Wir trennen den Text an den Zeilenumbrüchen auf, wählen die erste Zeile und ersetzen dort die Abschnittnummer.
Anschließend korrigieren wir die Prozessart in den Ausnahmefällen manuell.
Dafür fahren wir wie in Abbildung 10 mit der Maus in die zu bearbeitende Zelle, worauf ein blaues Bedienelement mit dem Text &amp;ldquo;Edit&amp;rdquo; es uns erlaubt in den Bearbeitungsmodus für diese Zelle zu wechseln.&lt;/p>
&lt;figure id="figure-bildschirmfoto-der-edit-funktionalität-in-openrefine">
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img alt="Bildschirmfoto der &amp;#39;Edit&amp;#39;-Funktionalität in OpenRefine." srcset="
/post/2021-07-findbuecher-mit-openrefine-in-datenbank-uebernehmen/openrefine-edit-prozessart_hueac7ef049c1393811c59b6c953ba3d8c_17548_94926e056d45232cbb94416d31a817f7.webp 400w,
/post/2021-07-findbuecher-mit-openrefine-in-datenbank-uebernehmen/openrefine-edit-prozessart_hueac7ef049c1393811c59b6c953ba3d8c_17548_edd06836278122286e3c1be2ee1b9272.webp 760w,
/post/2021-07-findbuecher-mit-openrefine-in-datenbank-uebernehmen/openrefine-edit-prozessart_hueac7ef049c1393811c59b6c953ba3d8c_17548_1200x1200_fit_q75_h2_lanczos_3.webp 1200w"
src="https://fdmlab.landesarchiv-bw.de/post/2021-07-findbuecher-mit-openrefine-in-datenbank-uebernehmen/openrefine-edit-prozessart_hueac7ef049c1393811c59b6c953ba3d8c_17548_94926e056d45232cbb94416d31a817f7.webp"
width="692"
height="314"
loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;figcaption data-pre="Abbildung&amp;nbsp;" data-post=":&amp;nbsp;" class="numbered">
Bildschirmfoto der &amp;lsquo;Edit&amp;rsquo;-Funktionalität in OpenRefine.
&lt;/figcaption>&lt;/figure>
&lt;h4 id="gegenstand">Gegenstand&lt;/h4>
&lt;p>Die Spalte Prozessart haben wir schon manuell korigiert. Um uns diesen Schritt für die Spalte Gegenstand zu sparen, gehen wir in der nächsten &amp;ldquo;Expression&amp;rdquo; wie folgt vor:&lt;/p>
&lt;ol>
&lt;li>Ersetze die Abschnittnummer&lt;/li>
&lt;li>Ersetze alle Zeilenumbrüche&lt;/li>
&lt;li>Entferne die Prozessart durch Ersetzung mit dem Inhalt der Spalte Prozessart.&lt;/li>
&lt;/ol>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="nx">value&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">replace&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sr">/^5\s{2,}/&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">.&lt;/span>&lt;span class="nx">replace&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sr">/-\n\s*(?![A-Z])/&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">.&lt;/span>&lt;span class="nx">replace&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sr">/(?&amp;lt;=-)\n\s*(?=[A-Z])/&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">.&lt;/span>&lt;span class="nx">replace&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sr">/\n\s*/&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34; &amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">.&lt;/span>&lt;span class="nx">replace&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">cells&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s2">&amp;#34;Prozessart&amp;#34;&lt;/span>&lt;span class="p">].&lt;/span>&lt;span class="nx">value&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">.&lt;/span>&lt;span class="nx">trim&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="abschnitt-6-vorinstanzen">Abschnitt 6 (Vorinstanzen)&lt;/h3>
&lt;p>Wir wechseln mit dem “Facet” zu Abschnitt 6 und übernehmen hier den kompletten Inhalt. Die Formatierung (Zeilenumbrüche, &amp;hellip;) wollen wir hier beibehalten.
Lediglich die Abschnittnummer entfernen wir.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="nx">value&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">replace&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sr">/^6/&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34; &amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="abschnitt-7-darin">Abschnitt 7 (Darin)&lt;/h3>
&lt;p>Wir wechseln mit dem “Facet” zu Abschnitt 7 und übernehmen hier den kompletten Inhalt.
Die Zeilenumbrüche wollen wir entfernen, dabei aber jedes Q in einer neuen Zeile stehen haben.&lt;/p>
&lt;p>Dabei gehen wir wie folgt vor:&lt;/p>
&lt;ol>
&lt;li>Abschnittnummer entfernen&lt;/li>
&lt;li>Zeilenumbrüche vor &lt;code>Q&lt;/code> mit Trennsequzenz ersetzen&lt;/li>
&lt;li>Zeilenumbrüche vor &lt;code>ohne Q&lt;/code> mit Trennsequzenz ersetzen&lt;/li>
&lt;li>Zeilenumbrüche mit Bindestrich (anschließend Kleinschreibung) entfernen&lt;/li>
&lt;li>Zeilenumbrüche mit Bindestrich (anschließend Großschreibung) entfernen&lt;/li>
&lt;li>Restliche Zeilenumbrüche mit Leerzeichen ersetzen&lt;/li>
&lt;li>Trennsequzenz durch Zeilenumbrüche und Leerzeichen für Formatierung ersetzen&lt;/li>
&lt;/ol>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="nx">value&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">replace&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sr">/^7/&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34; &amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">.&lt;/span>&lt;span class="nx">replace&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sr">/\s*\n\s+(?=Q\s*\d)/&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;-:::-&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">.&lt;/span>&lt;span class="nx">replace&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sr">/\s*\n\s+(?=ohne Q\s*)/&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;-:::-&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">.&lt;/span>&lt;span class="nx">replace&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sr">/-\n\s*(?![A-Z])/&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">.&lt;/span>&lt;span class="nx">replace&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sr">/(?&amp;lt;=-)\n\s*(?=[A-Z])/&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">.&lt;/span>&lt;span class="nx">replace&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sr">/\n\s*/&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34; &amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">.&lt;/span>&lt;span class="nx">replace&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sr">/-:::-/&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;\n &amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="abschnitt-8-umfang-stapelhöhe-hinweise">Abschnitt 8 (Umfang, Stapelhöhe, Hinweise)&lt;/h3>
&lt;p>Wir wechseln mit dem “Facet” zu Abschnitt 8.
In diesem Abschnitt haben wir mehrere Bestandteile, die wir in separate Spalten extrahieren wollen.&lt;/p>
&lt;blockquote>
&lt;div class="entities" style="line-height: 2.5; direction: ltr"> Q 1– 39&lt;br> &lt;mark class="entity" style="background: #b3e2cd; padding: 0.45em 0.6em; margin: 0 0.25em; line-height: 1; border-radius: 0.35em;">3 cm &lt;span style="font-size: 0.8em; font-weight: bold; line-height: 1; border-radius: 0.35em; vertical-align: middle; margin-left: 0.5rem">Stapelhöhe&lt;/span>&lt;/mark>&lt;br> ohne Wetzlarer Nummer, da vor Generalausteilung abgegeben (an Nach-&lt;br> folgeinstanz?)&lt;/div>
&lt;/blockquote>
&lt;p>Die Stapelhöhe bietet sich hier als Trennmerkmal an, da sie einfach zu identifizieren ist.
Bei Einträgen ohne Stapelhöhe können wir die Trennung manuell vornehmen.
Bei komplexeren Angaben können die verwendeten regulären Ausdrücke auch erweitert werden.&lt;/p>
&lt;h4 id="umfang">Umfang&lt;/h4>
&lt;p>Um den Umfang zu extrahieren, teilen wir den Eintrag bei der Stapelhöhe und entfernen die Abschnittnummer.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="nx">value&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">split&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sr">/\d+\s+cm/&lt;/span>&lt;span class="p">)[&lt;/span>&lt;span class="mi">0&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">.&lt;/span>&lt;span class="nx">replace&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sr">/^8\s+/&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">.&lt;/span>&lt;span class="nx">trim&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Ein Eintrag muss manuell nachbearbeitet werden.&lt;/p>
&lt;h4 id="stapelhöhe">Stapelhöhe&lt;/h4>
&lt;p>Die Stapelhöhe extrahieren wir direkt mit einem regulären Ausdruck.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="nx">value&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">find&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sr">/\d+\s+cm/&lt;/span>&lt;span class="p">)[&lt;/span>&lt;span class="mi">0&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h4 id="hinweise">Hinweise&lt;/h4>
&lt;p>Die Hinweise stehen nach der Stapelhöhe. Daher teilen wir den Eintrag bei der Stapelhöhe, nehmen den hinteren Teil, und entfernen die Zeilenumbrüche.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="nx">value&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">split&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sr">/\d+\s+cm/&lt;/span>&lt;span class="p">).&lt;/span>&lt;span class="nx">slice&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">1&lt;/span>&lt;span class="p">).&lt;/span>&lt;span class="nx">join&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">.&lt;/span>&lt;span class="nx">replace&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sr">/-\n\s*(?![A-Z])/&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">.&lt;/span>&lt;span class="nx">replace&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sr">/(?&amp;lt;=-)\n\s*(?=[A-Z])/&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">.&lt;/span>&lt;span class="nx">replace&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sr">/\n\s*/&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34; &amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">.&lt;/span>&lt;span class="nx">trim&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Ein Eintrag muss manuell nachbearbeitet werden.&lt;/p>
&lt;h3 id="nacharbeiten">Nacharbeiten&lt;/h3>
&lt;p>An dieser Stelle ist es soweit, dass wir die Spalten umsortieren, überflüssige Spalten löschen, die Zeilen zusammenfassen und die Daten noch einmal visuell prüfen.&lt;/p>
&lt;h4 id="spalte-abschnitt-löschen">Spalte Abschnitt löschen&lt;/h4>
&lt;p>Die Spalte Abschnitt wird nicht mehr benötigt und sie kann gelöscht werden.
&amp;ldquo;Abschnitt&amp;quot;
&lt;i class="far fa-caret-square-down pr-1 fa-fw">&lt;/i>&amp;quot;Edit column&amp;quot;
&lt;i class="fas fa-caret-right pr-1 fa-fw">&lt;/i>&amp;quot;Remove this column&amp;rdquo;&lt;/p>
&lt;h4 id="zeilen-zusammenfassen">Zeilen zusammenfassen&lt;/h4>
&lt;p>Bei der Spalte Original verbinden wir mit der Trennsequenz &lt;code>-:::-&lt;/code> über &amp;ldquo;Original&amp;quot;
&lt;i class="far fa-caret-square-down pr-1 fa-fw">&lt;/i>&amp;quot;Edit cells&amp;quot;
&lt;i class="fas fa-caret-right pr-1 fa-fw">&lt;/i>&amp;quot;Join multi-valued cells&amp;hellip;&amp;rdquo;. Die Trennsequenz ersetzen wir anschließend via &amp;ldquo;Original&amp;quot;
&lt;i class="far fa-caret-square-down pr-1 fa-fw">&lt;/i>&amp;quot;Edit cells&amp;quot;
&lt;i class="fas fa-caret-right pr-1 fa-fw">&lt;/i>&amp;quot;Transform&amp;hellip;&amp;rdquo;.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="nx">value&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">replace&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;-:::-&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;\n&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Die anderen Spalten (Hinweise, Stapelhöhe, Umfang, Darin, Vorinstanzen, Gegenstand, Prozessart, Prokuratoren, Beklagte, Kläger) verbinden wir ohne Trennzeichen, da es hier ja nur einen Wer pro &amp;ldquo;record&amp;rdquo; gibt.&lt;/p>
&lt;p>Jetzt sollten wir wieder genausowiele Zeilen (&amp;ldquo;rows&amp;rdquo;) wie &amp;ldquo;records&amp;rdquo; haben.&lt;/p>
&lt;h4 id="spalten-sortieren">Spalten sortieren&lt;/h4>
&lt;p>Jetzt können die Spalten via &amp;ldquo;All&amp;quot;
&lt;i class="far fa-caret-square-down pr-1 fa-fw">&lt;/i>&amp;quot;Edit columns&amp;quot;
&lt;i class="fas fa-caret-right pr-1 fa-fw">&lt;/i>&amp;quot;Re-order / remove columns&amp;hellip;&amp;rdquo; noch sortiert werden.&lt;/p>
&lt;h4 id="visuell-inspizieren">Visuell inspizieren&lt;/h4>
&lt;p>Jetzt kommt noch einmal ein visueller Abgleich der extrahierten Daten mit dem Original.
Die Spalte Original kann danach auch gelöscht werden (&amp;ldquo;Original&amp;quot;
&lt;i class="far fa-caret-square-down pr-1 fa-fw">&lt;/i>&amp;quot;Edit column&amp;quot;
&lt;i class="fas fa-caret-right pr-1 fa-fw">&lt;/i>&amp;quot;Remove this column&amp;rdquo;). Das Ergebnis ist in Abbildung 11 gezeigt.&lt;/p>
&lt;figure id="figure-bildschirmfoto-der-bereinigten-daten-in-openrefine">
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img alt="Bildschirmfoto der bereinigten Daten in OpenRefine." srcset="
/post/2021-07-findbuecher-mit-openrefine-in-datenbank-uebernehmen/openrefine-daten-uebersicht_hue7d96f5f6eeadc11e8a721db2fa25c32_118208_c616ef63cd17f7789628e07259ec8434.webp 400w,
/post/2021-07-findbuecher-mit-openrefine-in-datenbank-uebernehmen/openrefine-daten-uebersicht_hue7d96f5f6eeadc11e8a721db2fa25c32_118208_331bfd1e353e74dd44cb84efc115e313.webp 760w,
/post/2021-07-findbuecher-mit-openrefine-in-datenbank-uebernehmen/openrefine-daten-uebersicht_hue7d96f5f6eeadc11e8a721db2fa25c32_118208_1200x1200_fit_q75_h2_lanczos_3.webp 1200w"
src="https://fdmlab.landesarchiv-bw.de/post/2021-07-findbuecher-mit-openrefine-in-datenbank-uebernehmen/openrefine-daten-uebersicht_hue7d96f5f6eeadc11e8a721db2fa25c32_118208_c616ef63cd17f7789628e07259ec8434.webp"
width="760"
height="355"
loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;figcaption data-pre="Abbildung&amp;nbsp;" data-post=":&amp;nbsp;" class="numbered">
Bildschirmfoto der bereinigten Daten in OpenRefine.
&lt;/figcaption>&lt;/figure>
&lt;h4 id="export">Export&lt;/h4>
&lt;p>Die Daten können wir über &amp;ldquo;Export&amp;quot;
&lt;i class="far fa-caret-square-down pr-1 fa-fw">&lt;/i>&amp;quot;Comma-separated value&amp;rdquo; als CSV-Datei exportieren.
Das machen wir, da wir für die Transformation der Daten auf das Datenbankschema ein separates Projekt erstellen wollen.&lt;/p>
&lt;p>Diese Trennung in zwei Projekte ist Geschmackssache.
Es hat sich jedoch gezeigt, dass es gerade bei der Übertragung der Daten auf das Erfassungsschema Abstimmungsbedarf und gegebenenfalls mehrerer Iterationen bedarf.
Daher hat sich diese Aufteilung in zwei getrennte Arbeitsschritte und Projekte bei uns etabliert.&lt;/p>
&lt;blockquote>
&lt;p>💾 Die einzelnen Arbeitsschritte im OpenRefine Format:&lt;/p>
&lt;/blockquote>
&lt;a href="https://fdmlab.landesarchiv-bw.de/data/rkg-57/akten-rkg-band-57-wertheim-openrefine-txt.json" target="_blank">
&lt;i class="fas fa-file-archive pr-1 fa-fw">&lt;/i>Inventar Akten RKG Band 57 - Wertheim als OpenRefine Arbeitsschritte&lt;/a>
.
&lt;h2 id="4-tabelle-auf-datenbankschema-übertragen">4. Tabelle auf Datenbankschema übertragen&lt;/h2>
&lt;p>Wir haben in Teil 3 den Text des Inventars des Findbuchs in strukturierte Daten umgewandelt.
In diesem Teil wandeln wir diese Daten in unser Erfassungs- bzw. Datenbankschema um. Anders ausgedrückt: Wir bringen die Daten in eine Form, die es uns erlaubt, sie auf die Felder unseres Erschließungsformulars im AFIS zu mappen.&lt;/p>
&lt;blockquote>
&lt;p>💾 Die Datei mit den strukturierten Daten für diesen Teil:&lt;/p>
&lt;/blockquote>
&lt;a href="https://fdmlab.landesarchiv-bw.de/data/rkg-57/akten-rkg-band-57-wertheim.csv" target="_blank">
&lt;i class="fas fa-file-csv pr-1 fa-fw">&lt;/i>Inventar Akten RKG Band 57 - Wertheim als CSV&lt;/a>
.
&lt;h3 id="import">Import&lt;/h3>
&lt;p>Wir erstellen ein neues Projekt in OpenRefine und importieren dafür die CSV Datei.
OpenRefine erkennt automatisch die passenden Einstellungen und wir passen lediglich den Projektnamen und die Schlagworte an.
Siehe dazu Abbildung 12.&lt;/p>
&lt;figure id="figure-bildschirmfoto-der-einstellungen-zum-import-der-csv-datei-in-openrefine">
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img alt="Bildschirmfoto der Einstellungen zum Import der CSV-Datei in OpenRefine." srcset="
/post/2021-07-findbuecher-mit-openrefine-in-datenbank-uebernehmen/openrefine-create-db-settings_hu01def4a5f868504ab7cc8e0012fe3607_137624_f5d65e24f766d31f8288a945c528844c.webp 400w,
/post/2021-07-findbuecher-mit-openrefine-in-datenbank-uebernehmen/openrefine-create-db-settings_hu01def4a5f868504ab7cc8e0012fe3607_137624_dab575ce2e0209004cbf908fcd7d561c.webp 760w,
/post/2021-07-findbuecher-mit-openrefine-in-datenbank-uebernehmen/openrefine-create-db-settings_hu01def4a5f868504ab7cc8e0012fe3607_137624_1200x1200_fit_q75_h2_lanczos_3.webp 1200w"
src="https://fdmlab.landesarchiv-bw.de/post/2021-07-findbuecher-mit-openrefine-in-datenbank-uebernehmen/openrefine-create-db-settings_hu01def4a5f868504ab7cc8e0012fe3607_137624_f5d65e24f766d31f8288a945c528844c.webp"
width="760"
height="362"
loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;figcaption data-pre="Abbildung&amp;nbsp;" data-post=":&amp;nbsp;" class="numbered">
Bildschirmfoto der Einstellungen zum Import der CSV-Datei in OpenRefine.
&lt;/figcaption>&lt;/figure>
&lt;h3 id="transformation">Transformation&lt;/h3>
&lt;p>Da wir schon strukturierte Daten haben, fällt dieser Abschnitt etwas kürzer aus.
Hier geht es hauptsächlich darum einzelne Spalten zusammenzufassen, gegebenenfalls mit Text zu ergänzen und manchmal auch umzuwandeln.&lt;/p>
&lt;h4 id="titel">Titel&lt;/h4>
&lt;p>Hier wollen wir, dass der Kläger im Titelfeld steht und dass der Titel mit &amp;ldquo;Kläger:&amp;rdquo; beginnt. Unser Titel soll also die Form &amp;ldquo;Kläger: {Kläger}&amp;rdquo; haben.
Dafür wandeln wir die Spalte einfach via &amp;ldquo;Kläger&amp;quot;
&lt;i class="far fa-caret-square-down pr-1 fa-fw">&lt;/i>&amp;quot;Edit cells&amp;quot;
&lt;i class="fas fa-caret-right pr-1 fa-fw">&lt;/i>&amp;quot;Transform&amp;hellip;&amp;rdquo; um:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="s2">&amp;#34;Kläger: &amp;#34;&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="nx">value&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Anschließend benennen wir die Spalte via &amp;ldquo;Kläger&amp;quot;
&lt;i class="far fa-caret-square-down pr-1 fa-fw">&lt;/i>&amp;quot;Edit column&amp;quot;
&lt;i class="fas fa-caret-right pr-1 fa-fw">&lt;/i>&amp;quot;Rename this column&amp;rdquo; in &amp;ldquo;Titel&amp;rdquo; um.&lt;/p>
&lt;p>Um die Übersicht zu behalten, verschieben wir diese Spalte mit &amp;ldquo;Titel&amp;quot;
&lt;i class="far fa-caret-square-down pr-1 fa-fw">&lt;/i>&amp;quot;Edit column&amp;quot;
&lt;i class="fas fa-caret-right pr-1 fa-fw">&lt;/i>&amp;quot;Move column to end&amp;rdquo; direkt an das Ende.&lt;/p>
&lt;h4 id="bestellsignatur">Bestellsignatur&lt;/h4>
&lt;p>Für die Bestellsignatur ergänzen wir zur Findbuch Nummer in der Spalte Nr die Bestandssignatur &lt;code>R J 10&lt;/code>.
Dafür transformieren wir via &amp;ldquo;Nr&amp;quot;
&lt;i class="far fa-caret-square-down pr-1 fa-fw">&lt;/i>&amp;quot;Edit cells&amp;quot;
&lt;i class="fas fa-caret-right pr-1 fa-fw">&lt;/i>&amp;quot;Transform&amp;hellip;&amp;rdquo;&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="s2">&amp;#34;R J 10 &amp;#34;&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="nx">value&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Danach benennen wir die Spalte via &amp;ldquo;Nr&amp;quot;
&lt;i class="far fa-caret-square-down pr-1 fa-fw">&lt;/i>&amp;quot;Edit column&amp;quot;
&lt;i class="fas fa-caret-right pr-1 fa-fw">&lt;/i>&amp;quot;Rename this column&amp;rdquo; in &amp;ldquo;Bestellsignatur&amp;rdquo; um.&lt;/p>
&lt;p>Anschließend sind wir mit dieser Spalte fertig und verschieben sie via &amp;ldquo;Bestellsignatur&amp;quot;
&lt;i class="far fa-caret-square-down pr-1 fa-fw">&lt;/i>&amp;quot;Edit column&amp;quot;
&lt;i class="fas fa-caret-right pr-1 fa-fw">&lt;/i>&amp;quot;Move column to end&amp;rdquo; direkt an das Ende.&lt;/p>
&lt;h4 id="vorsignatur-1">Vorsignatur 1&lt;/h4>
&lt;p>Hier können wir direkt die Spalte Altsignatur umbennen und an das Ende verschieben.&lt;/p>
&lt;h4 id="vorsignatur-2">Vorsignatur 2&lt;/h4>
&lt;p>Hier können wir direkt die Spalte Vorsignatur umbennen und an das Ende verschieben.&lt;/p>
&lt;h4 id="entstehungszeitraum">Entstehungszeitraum&lt;/h4>
&lt;p>Wir haben beschlossen, dass wir als Entstehungszeitraum die niedrigste Jahreszahl der Laufzeit bis zur höchsten Jahreszahl der Laufzeit verwenden.
Diese müssen aus der Laufzeit erst noch extrahiert und in das AFIS Importformat umgewandelt werden.&lt;/p>
&lt;p>Um die original Schreibweise zu erhalten, wird diese im nächsten Feld (Entstehungszeitraum, Anm.) übernommen.&lt;/p>
&lt;p>Also erstellen wir hier eine neue Spalte aus der Spalte Laufzeit durch folgende Operationen:&lt;/p>
&lt;ol>
&lt;li>Ersetze alles was keine Ziffer ist &lt;code>\D&lt;/code> durch ein Leerzeichen.&lt;/li>
&lt;li>Ersetze mehrere Leerzeichen hintereinander &lt;code>\s+&lt;/code> durch &lt;strong>ein&lt;/strong> Leerzeichen.&lt;/li>
&lt;li>Entferne Leerzeichen zu Beginn und Ende der Laufzeit mit &lt;code>trim()&lt;/code>.&lt;/li>
&lt;li>Teile den Text an Leerzeichen mit &lt;code>split()&lt;/code>.&lt;/li>
&lt;li>Sortiere die Liste (technisch ein &lt;a href="https://docs.openrefine.org/manual/grelfunctions#array-functions" target="_blank" rel="noopener">Array&lt;/a>) mit &lt;code>sort()&lt;/code>.&lt;/li>
&lt;li>Die Liste wird &lt;code>arr&lt;/code> genannt (via &lt;code>with&lt;/code>).&lt;/li>
&lt;li>Wenn die Liste mehr als ein Element beinhaltet, nehmen wir das erste &lt;code>arr[0]&lt;/code> und letzte Element &lt;code>arr[-1]&lt;/code> aus der sortierten Liste.&lt;/li>
&lt;li>Wenn die Liste nur ein Element beinhaltet, nehmen wir dieses.&lt;/li>
&lt;li>(indirekt) Bei Fehlern, wird das Feld einfach nicht ausgefüllt.&lt;/li>
&lt;/ol>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="kd">with&lt;/span>&lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">value&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">replace&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sr">/\D/&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34; &amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">.&lt;/span>&lt;span class="nx">replace&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sr">/\s+/&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34; &amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">.&lt;/span>&lt;span class="nx">trim&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">.&lt;/span>&lt;span class="nx">split&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34; &amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">.&lt;/span>&lt;span class="nx">sort&lt;/span>&lt;span class="p">(),&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">arr&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">arr&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">length&lt;/span>&lt;span class="p">()&lt;/span> &lt;span class="o">&amp;gt;&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;&amp;gt;=&amp;lt;= +&amp;#34;&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="nx">arr&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="mi">0&lt;/span>&lt;span class="p">]&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="s2">&amp;#34; +&amp;#34;&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="nx">arr&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="o">-&lt;/span>&lt;span class="mi">1&lt;/span>&lt;span class="p">],&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;= +&amp;#34;&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="nx">arr&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="mi">0&lt;/span>&lt;span class="p">]))&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Anschließend verschieben wir die neue Spalte an das Ende.&lt;/p>
&lt;h4 id="entstehungszeitraum-anm">Entstehungszeitraum, Anm.&lt;/h4>
&lt;p>Hier können wir direkt die Spalte Laufzeit umbennen und an das Ende verschieben.&lt;/p>
&lt;h4 id="beklagte">Beklagte&lt;/h4>
&lt;p>Diese Spalte übernehmen wir direkt so und verschieben sie an das Ende.&lt;/p>
&lt;h4 id="bemerkung">Bemerkung&lt;/h4>
&lt;p>In dieser Spalte fassen wir die Spalten Vorinstanzen und Hinweise zusammen.
Hier gibt es mehrere Möglichkeiten die Spalten zusammen zu fassen.&lt;/p>
&lt;h5 id="technische-variante">Technische Variante&lt;/h5>
&lt;p>Bei der ersten, technischeren Variante erstellen wir eine neue Spalte basierend auf der Spalte Vorinstanzen und fügen dabei den Wert der Spalte Hinweise hinzu.
Dabei ist zu beachten, dass wir die Werte nur verwenden, wenn sie auch vorhanden sind &lt;code>isNonBlank&lt;/code>.
Sonst kommt es zu einem Fehler und die Zielspalte bleibt leer, wenn zum Beispiel für einen Eintrag nur die Vorinstanzen belegt sind.&lt;/p>
&lt;p>Von der Spalte Vorinstanzen ausgehend erzeugen wir eine neue Spalte Bemerkung mit folgender &amp;ldquo;Expression&amp;rdquo;:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">isNonBlank&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">value&lt;/span>&lt;span class="p">),&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;Vorinstanzen, Anfangsjahr:\n&amp;#34;&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="nx">value&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="o">+&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">isNonBlank&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">cells&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s2">&amp;#34;Hinweise&amp;#34;&lt;/span>&lt;span class="p">]),&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;\n\nHinweise: &amp;#34;&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="nx">cells&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s2">&amp;#34;Hinweise&amp;#34;&lt;/span>&lt;span class="p">].&lt;/span>&lt;span class="nx">value&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;&amp;#34;&lt;/span>&lt;span class="p">))&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">.&lt;/span>&lt;span class="nx">trim&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Anschließend löschen wir die Spalten Vorinstanzen und Hinweise und verschieben die neue Spalte Bemerkung an das Ende.&lt;/p>
&lt;h5 id="weniger-technische-variante">Weniger technische Variante&lt;/h5>
&lt;p>Bei der weniger technischen Variante transformieren wir zuerst die Spalte Vorinstanzen:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="k">if&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">isNonBlank&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">value&lt;/span>&lt;span class="p">),&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;Vorinstanzen, Anfangsjahr:\n&amp;#34;&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="nx">value&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Dann transformieren wir die Spalte Hinweise:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="k">if&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">isNonBlank&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">cells&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s2">&amp;#34;Hinweise&amp;#34;&lt;/span>&lt;span class="p">]),&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;\n\nHinweise: &amp;#34;&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="nx">cells&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s2">&amp;#34;Hinweise&amp;#34;&lt;/span>&lt;span class="p">].&lt;/span>&lt;span class="nx">value&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Anschließend verbinden wir die beiden Spalten via &amp;ldquo;Vorinstanzen&amp;quot;
&lt;i class="far fa-caret-square-down pr-1 fa-fw">&lt;/i>&amp;quot;Edit column&amp;quot;
&lt;i class="fas fa-caret-right pr-1 fa-fw">&lt;/i>&amp;quot;Join columns&amp;hellip;&amp;rdquo;.
Dabei können wir die Original Spalten Vorinstanzen und Hinweise auch gleich löschen. Siehe dazu Abbildung 13.&lt;/p>
&lt;figure id="figure-bildschirmfoto-der-einstellungen-zum-verbinden-der-spalten-vorinstanzen-und-hinweise-in-openrefine">
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img alt="Bildschirmfoto der Einstellungen zum Verbinden der Spalten Vorinstanzen und Hinweise in OpenRefine." srcset="
/post/2021-07-findbuecher-mit-openrefine-in-datenbank-uebernehmen/openrefine-join-columns_hu758a7a4d0dc133cf90137b645178b4fb_32557_7c1eccb8bff53265486780fb516c4cfd.webp 400w,
/post/2021-07-findbuecher-mit-openrefine-in-datenbank-uebernehmen/openrefine-join-columns_hu758a7a4d0dc133cf90137b645178b4fb_32557_7cb4b95f9772b3349d54f79fef805e97.webp 760w,
/post/2021-07-findbuecher-mit-openrefine-in-datenbank-uebernehmen/openrefine-join-columns_hu758a7a4d0dc133cf90137b645178b4fb_32557_1200x1200_fit_q75_h2_lanczos_3.webp 1200w"
src="https://fdmlab.landesarchiv-bw.de/post/2021-07-findbuecher-mit-openrefine-in-datenbank-uebernehmen/openrefine-join-columns_hu758a7a4d0dc133cf90137b645178b4fb_32557_7c1eccb8bff53265486780fb516c4cfd.webp"
width="760"
height="433"
loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;figcaption data-pre="Abbildung&amp;nbsp;" data-post=":&amp;nbsp;" class="numbered">
Bildschirmfoto der Einstellungen zum Verbinden der Spalten Vorinstanzen und Hinweise in OpenRefine.
&lt;/figcaption>&lt;/figure>
&lt;p>Die neue Spalte Bemerkung schieben wir an das Ende.&lt;/p>
&lt;h4 id="enthält">Enthält&lt;/h4>
&lt;p>Hier fassen wir die Spalten Gegenstand, Darin und Prokuratoren zusammen.&lt;/p>
&lt;p>Von der Spalte Gegenstand ausgehend erzeugen wir eine neue Spalte Enthält mit folgender &amp;ldquo;Expression&amp;rdquo;:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">isNonBlank&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">value&lt;/span>&lt;span class="p">),&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;Gegenstand materiell:\n &amp;#34;&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="nx">value&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="o">+&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">isNonBlank&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">cells&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s2">&amp;#34;Darin&amp;#34;&lt;/span>&lt;span class="p">]),&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;\n\nDarin:\n&amp;#34;&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="nx">cells&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s2">&amp;#34;Darin&amp;#34;&lt;/span>&lt;span class="p">].&lt;/span>&lt;span class="nx">value&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="o">+&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">isNonBlank&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">cells&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s2">&amp;#34;Prokuratoren&amp;#34;&lt;/span>&lt;span class="p">]),&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;\n\nProkuratoren mit Bevollmächtigungsjahr:\n&amp;#34;&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="nx">cells&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s2">&amp;#34;Prokuratoren&amp;#34;&lt;/span>&lt;span class="p">].&lt;/span>&lt;span class="nx">value&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;&amp;#34;&lt;/span>&lt;span class="p">))&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">.&lt;/span>&lt;span class="nx">trim&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Die Spalten Gegenstand, Darin und Prokuratoren löschen wir anschließend und die neue Spalte Enthält verschieben wir an das Ende.&lt;/p>
&lt;h4 id="gegenstand-1">Gegenstand&lt;/h4>
&lt;p>Hier können wir direkt die Spalte Prozessart umbennen und an das Ende verschieben.&lt;/p>
&lt;h4 id="umfang-1">Umfang&lt;/h4>
&lt;p>Wir haben uns dazu entschlossen den Umfang und die Stapelhöhe in einem Feld zu erfassen und führen sie daher wieder zusammen.&lt;/p>
&lt;p>Um uns das Umbenennen der Spalte Umfang zu sparen, transformieren wir die Spalte anstatt eine neue Spalte zu erzeugen.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">value&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="o">+&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">isNonBlank&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">cells&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s2">&amp;#34;Stapelhöhe&amp;#34;&lt;/span>&lt;span class="p">]),&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;\n&amp;#34;&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="nx">cells&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s2">&amp;#34;Stapelhöhe&amp;#34;&lt;/span>&lt;span class="p">].&lt;/span>&lt;span class="nx">value&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;&amp;#34;&lt;/span>&lt;span class="p">))&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">.&lt;/span>&lt;span class="nx">trim&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Anschließend löschen wir die Spalte Stapelhöhe und verschieben die Spalte Umfang an das Ende.
Die Daten sind nun in ihrem Zielformat und sind in Abbildung 14 abgebildet.&lt;/p>
&lt;figure id="figure-bildschirmfoto-der-bereinigten-daten-in-openrefine">
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img alt="Bildschirmfoto der bereinigten Daten in OpenRefine." srcset="
/post/2021-07-findbuecher-mit-openrefine-in-datenbank-uebernehmen/openrefine-daten-uebersicht-db_hue1a572288dee0ca50ad4409666b23711_91382_8d34b872be45e366760a417dfb944af9.webp 400w,
/post/2021-07-findbuecher-mit-openrefine-in-datenbank-uebernehmen/openrefine-daten-uebersicht-db_hue1a572288dee0ca50ad4409666b23711_91382_dcfd3271ec79aa08cc6a8e4577e122b2.webp 760w,
/post/2021-07-findbuecher-mit-openrefine-in-datenbank-uebernehmen/openrefine-daten-uebersicht-db_hue1a572288dee0ca50ad4409666b23711_91382_1200x1200_fit_q75_h2_lanczos_3.webp 1200w"
src="https://fdmlab.landesarchiv-bw.de/post/2021-07-findbuecher-mit-openrefine-in-datenbank-uebernehmen/openrefine-daten-uebersicht-db_hue1a572288dee0ca50ad4409666b23711_91382_8d34b872be45e366760a417dfb944af9.webp"
width="760"
height="398"
loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;figcaption data-pre="Abbildung&amp;nbsp;" data-post=":&amp;nbsp;" class="numbered">
Bildschirmfoto der bereinigten Daten in OpenRefine.
&lt;/figcaption>&lt;/figure>
&lt;h3 id="export-1">Export&lt;/h3>
&lt;p>Die Daten werden nun über &amp;ldquo;Export&amp;quot;
&lt;i class="far fa-caret-square-down pr-1 fa-fw">&lt;/i>&amp;quot;Custom tabular exporter…&amp;rdquo; als CSV-Datei exportiert.
Die Einstellungen sind in Abbildung 15 gezeigt.&lt;/p>
&lt;figure id="figure-bildschirmfoto-der-einstellungen-für-den-export-in-openrefine">
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img alt="Bildschirmfoto der Einstellungen für den Export in OpenRefine." srcset="
/post/2021-07-findbuecher-mit-openrefine-in-datenbank-uebernehmen/openrefine-export-csv-custom_hub1a00db0525c7e9d5f3154d003b99d65_19895_ca6e5b88091033b235a194d224210831.webp 400w,
/post/2021-07-findbuecher-mit-openrefine-in-datenbank-uebernehmen/openrefine-export-csv-custom_hub1a00db0525c7e9d5f3154d003b99d65_19895_cf351030337c0f371e9ced3ac7324495.webp 760w,
/post/2021-07-findbuecher-mit-openrefine-in-datenbank-uebernehmen/openrefine-export-csv-custom_hub1a00db0525c7e9d5f3154d003b99d65_19895_1200x1200_fit_q75_h2_lanczos_3.webp 1200w"
src="https://fdmlab.landesarchiv-bw.de/post/2021-07-findbuecher-mit-openrefine-in-datenbank-uebernehmen/openrefine-export-csv-custom_hub1a00db0525c7e9d5f3154d003b99d65_19895_ca6e5b88091033b235a194d224210831.webp"
width="760"
height="363"
loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;figcaption data-pre="Abbildung&amp;nbsp;" data-post=":&amp;nbsp;" class="numbered">
Bildschirmfoto der Einstellungen für den Export in OpenRefine.
&lt;/figcaption>&lt;/figure>
&lt;p>Wir verwenden den &amp;ldquo;Custom tabular exporter&amp;rdquo;, da bei uns häufig Excel zum Inspizieren der Daten verwendet wird.
Excel erwartet bei CSV-Dateien jedoch ein Semikolon &lt;code>;&lt;/code> als Trennzeichen und &lt;code>iso-8859-1&lt;/code> als Kodierung.&lt;/p>
&lt;blockquote>
&lt;p>💾 Die Datei mit den strukturierten Daten für den Datenbank Import:&lt;/p>
&lt;/blockquote>
&lt;a href="https://fdmlab.landesarchiv-bw.de/data/rkg-57/akten-rkg-band-57-wertheim-db.csv" target="_blank">
&lt;i class="fas fa-file-csv pr-1 fa-fw">&lt;/i>Inventar Akten RKG Band 57 - Wertheim als CSV für Datenbank Import&lt;/a>
.
>
> 💾 Die einzelnen Arbeitsschritte im OpenRefine Format:
&lt;a href="https://fdmlab.landesarchiv-bw.de/data/rkg-57/akten-rkg-band-57-wertheim-openrefine-db.json" target="_blank">
&lt;i class="fas fa-file-archive pr-1 fa-fw">&lt;/i>Inventar Akten RKG Band 57 - Wertheim als OpenRefine Arbeitsschritte&lt;/a>
.
&lt;h2 id="fazit">Fazit&lt;/h2>
&lt;p>Wir haben mit OpenRefine ein komplettes, textbasiertes Findbuch in ein für den Datenbankimport kompatibles Format umgewandelt.
Dabei haben wir auf komplexe Code-Schleifen und Bedingungen verzichtet und dafür mehr manuelle Schritte vorgenommen.&lt;/p>
&lt;p>Die Fähigkeit von OpenRefine Änderungen an Daten und die Wirkung von Transformationen quasi live anzuzeigen, erlaubt es auch Einsteigern schnelle Fortschritte zu erzielen.
Mit den Erklärungen und dem Aufzeigen unterschiedlicher Lösungen haben wir Strategien aufgezeigt, die sich auf ähnliche Probleme übertragen lassen.&lt;/p>
&lt;p>Wir konnten zeigen, dass sich mit OpenRefine auch Texte in tabellenartige Formate transformieren lassen.
Es bleibt die Herausforderung passende Muster (reguläre Ausdrücke) zu finden, die es ermöglichen die Daten aus den Texten passend herauszufiltern.&lt;/p></description></item><item><title>Einträge analoger Findbüchern automatisiert in Datenbanken übernehmen - Reguläre Ausdrücke</title><link>https://fdmlab.landesarchiv-bw.de/post/2021-07-analoge-findbuecher-in-db-uebernehmen/</link><pubDate>Tue, 06 Jul 2021 00:00:00 +0000</pubDate><guid>https://fdmlab.landesarchiv-bw.de/post/2021-07-analoge-findbuecher-in-db-uebernehmen/</guid><description>&lt;p>Im FDMLab haben wir einige analoge Findbücher digitalisiert und die Einträge automatisiert in unsere Datenbanksysteme übernommen.
Dieser Blogbeitrag konzentriert sich auf die Extraktion der Informationen mit regulären Ausdrücken.&lt;/p>
&lt;p>Dabei gehen wir recht technisch vor und zeigen Codebeispiele in Python und mit &lt;a href="https://spacy.io/" target="_blank" rel="noopener">spaCy 3.0&lt;/a>.&lt;/p>
&lt;p>Bei spaCy handelt es sich um ein Python basiertes Framework für Natural Language Processing (NLP).
Wir konzentrieren uns hier auf einen kleinen Teil des Frameworks, nämlich das &lt;a href="https://spacy.io/usage/rule-based-matching" target="_blank" rel="noopener">regelbasierte Matching&lt;/a>.&lt;/p>
&lt;details class="toc-inpage d-print-none " open>
&lt;summary class="font-weight-bold">Inhaltsverzeichnis&lt;/summary>
&lt;nav id="TableOfContents">
&lt;ul>
&lt;li>&lt;a href="#einfache-reguläre-ausdrücke">Einfache reguläre Ausdrücke&lt;/a>&lt;/li>
&lt;li>&lt;a href="#mehrere-reguläre-ausdrücke">Mehrere reguläre Ausdrücke&lt;/a>&lt;/li>
&lt;li>&lt;a href="#regelbasiertes-matching-mit-spacy">Regelbasiertes Matching mit spaCy&lt;/a>&lt;/li>
&lt;li>&lt;a href="#erweitertes-regelbasiertes-matching-mit-spacy">Erweitertes regelbasiertes Matching mit spaCy&lt;/a>&lt;/li>
&lt;li>&lt;a href="#kombiniere-reguläre-ausdrücke-mit-spacy">Kombiniere reguläre Ausdrücke mit spaCy&lt;/a>&lt;/li>
&lt;li>&lt;a href="#fazit">Fazit&lt;/a>&lt;/li>
&lt;/ul>
&lt;/nav>
&lt;/details>
&lt;p>Folgende &lt;code>imports&lt;/code> sind notwendig um die Code-Beispiele auszuführen.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="kn">import&lt;/span> &lt;span class="nn">re&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">from&lt;/span> &lt;span class="nn">spacy&lt;/span> &lt;span class="kn">import&lt;/span> &lt;span class="n">displacy&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">from&lt;/span> &lt;span class="nn">spacy.lang.de&lt;/span> &lt;span class="kn">import&lt;/span> &lt;span class="n">German&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">from&lt;/span> &lt;span class="nn">spacy.matcher&lt;/span> &lt;span class="kn">import&lt;/span> &lt;span class="n">Matcher&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">from&lt;/span> &lt;span class="nn">spacy.tokens&lt;/span> &lt;span class="kn">import&lt;/span> &lt;span class="n">Span&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;div class="alert alert-note">
&lt;div>
Wir versuchen die (Code-)Beispiele so knapp und verständlich wie möglich zu halten.
Daher fehlen einige Details (Fehlerbehandlung, Spezialfälle, &amp;hellip;).
&lt;/div>
&lt;/div>
&lt;h2 id="einfache-reguläre-ausdrücke">Einfache reguläre Ausdrücke&lt;/h2>
&lt;p>Bei unseren Projekten zur Findbuchextraktion haben wir häufig die Situation, dass wir die Inhalte eines Textblocks auf mehrere Felder in der Zieldatenbank mappen.&lt;/p>
&lt;p>Hier haben wir ein markiertes Beispiel für den Beginn eines Findbucheintrages.&lt;/p>
&lt;div class="entities" style="line-height: 2.5; direction: ltr">
&lt;mark class="entity" style="background: #b3e2cd; padding: 0.45em 0.6em; margin: 0 0.25em; line-height: 1; border-radius: 0.35em;">
42
&lt;span style="font-size: 0.8em; font-weight: bold; line-height: 1; border-radius: 0.35em; vertical-align: middle; margin-left: 0.5rem">NR&lt;/span>
&lt;/mark>
&lt;mark class="entity" style="background: #fdcdac; padding: 0.45em 0.6em; margin: 0 0.25em; line-height: 1; border-radius: 0.35em;">
HSTA L13 42
&lt;span style="font-size: 0.8em; font-weight: bold; line-height: 1; border-radius: 0.35em; vertical-align: middle; margin-left: 0.5rem">SIG&lt;/span>
&lt;/mark>
(
&lt;mark class="entity" style="background: #cbd5e8; padding: 0.45em 0.6em; margin: 0 0.25em; line-height: 1; border-radius: 0.35em;">
A9594
&lt;span style="font-size: 0.8em; font-weight: bold; line-height: 1; border-radius: 0.35em; vertical-align: middle; margin-left: 0.5rem">ASIG&lt;/span>
&lt;/mark>
)
&lt;mark class="entity" style="background: #e6f5c9; padding: 0.45em 0.6em; margin: 0 0.25em; line-height: 1; border-radius: 0.35em;">
1798
&lt;span style="font-size: 0.8em; font-weight: bold; line-height: 1; border-radius: 0.35em; vertical-align: middle; margin-left: 0.5rem">DATUM&lt;/span>
&lt;/mark>
&lt;/div>
&lt;p>Hier sind die Findbuchnummer (NR), die Bestellsignatur (SIG), die Altsignatur (ASIG), die Vorsignatur (VSIG) und ein zugehöriges Datum (DATUM) der Archivalie in einer Zeile und sollen als einzelne Datenfelder extrahiert werden.&lt;/p>
&lt;p>Mit einem regulären Ausdruck und so genannten &amp;ldquo;named capturing groups&amp;rdquo; lassen sich die benötigten Datenschnippsel (Entities) extrahieren und direkt für die Datenbank weiterverarbeiten.&lt;/p>
&lt;p>&lt;strong>Code-Beispiel:&lt;/strong>&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="n">text1&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="s2">&amp;#34;42 HSTA L13 42 (A9594) 1798&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">pattern&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="s2">&amp;#34;^(?P&amp;lt;NR&amp;gt;\d+)\s+(?P&amp;lt;SIG&amp;gt;[^\(]+)\s+\((?P&amp;lt;ASIG&amp;gt;.+)\)\s+(?P&amp;lt;DATUM&amp;gt;\d+)$&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">re&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">match&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">pattern&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">text1&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">groupdict&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>&lt;strong>Ausgabe:&lt;/strong>&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="p">{&lt;/span>&lt;span class="s1">&amp;#39;NR&amp;#39;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s1">&amp;#39;42&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s1">&amp;#39;SIG&amp;#39;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s1">&amp;#39;HSTA L13 42&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s1">&amp;#39;ASIG&amp;#39;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s1">&amp;#39;A9594&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s1">&amp;#39;DATUM&amp;#39;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s1">&amp;#39;1798&amp;#39;&lt;/span>&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>&lt;strong>Aber:&lt;/strong> zumindest in den von uns bearbeiteten Findbüchern blieb das Schema nie so konsistent, als dass die Daten mit nur einem verständlichen regulären Ausdruck extrahiert werden konnten.
Hier eine weitere Zeile aus einem Findbucheintrag aus dem gleichen Band.&lt;/p>
&lt;div class="entities" style="line-height: 2.5; direction: ltr">
&lt;mark class="entity" style="background: #b3e2cd; padding: 0.45em 0.6em; margin: 0 0.25em; line-height: 1; border-radius: 0.35em;">
113a
&lt;span style="font-size: 0.8em; font-weight: bold; line-height: 1; border-radius: 0.35em; vertical-align: middle; margin-left: 0.5rem">NR&lt;/span>
&lt;/mark>
&lt;mark class="entity" style="background: #fdcdac; padding: 0.45em 0.6em; margin: 0 0.25em; line-height: 1; border-radius: 0.35em;">
HSTA L13 50-55c
&lt;span style="font-size: 0.8em; font-weight: bold; line-height: 1; border-radius: 0.35em; vertical-align: middle; margin-left: 0.5rem">SIG&lt;/span>
&lt;/mark>
(Vorsignatur:
&lt;mark class="entity" style="background: #f4cae4; padding: 0.45em 0.6em; margin: 0 0.25em; line-height: 1; border-radius: 0.35em;">
GLAK B33 F 7 13b
&lt;span style="font-size: 0.8em; font-weight: bold; line-height: 1; border-radius: 0.35em; vertical-align: middle; margin-left: 0.5rem">VSIG&lt;/span>
&lt;/mark>
,
&lt;mark class="entity" style="background: #cbd5e8; padding: 0.45em 0.6em; margin: 0 0.25em; line-height: 1; border-radius: 0.35em;">
T1234c
&lt;span style="font-size: 0.8em; font-weight: bold; line-height: 1; border-radius: 0.35em; vertical-align: middle; margin-left: 0.5rem">ASIG&lt;/span>
&lt;/mark>
)
&lt;mark class="entity" style="background: #e6f5c9; padding: 0.45em 0.6em; margin: 0 0.25em; line-height: 1; border-radius: 0.35em;">
ca. 18. Jhd.
&lt;span style="font-size: 0.8em; font-weight: bold; line-height: 1; border-radius: 0.35em; vertical-align: middle; margin-left: 0.5rem">DATUM&lt;/span>
&lt;/mark>
&lt;/div>
&lt;p>Hier funktioniert der oben gezeigte reguläre Ausdruck nicht mehr.&lt;/p>
&lt;p>&lt;strong>Code-Beispiel:&lt;/strong>&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="n">text2&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="s2">&amp;#34;113a HSTA L13 50-55c (Vorsignatur: GLAK B33 F 7 13b, T1234c) ca. 18. Jhd.&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">re&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">match&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">pattern&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">text2&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="ow">is&lt;/span> &lt;span class="kc">None&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>&lt;strong>Ausgabe:&lt;/strong>&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="kc">True&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Der Einsatz von einzelnen regulären Ausdrücken führte bei uns zu unübersichtlichen und nicht zu pflegenden Konstrukten.
Daher sind wir dazu übergegangen, die unterschiedlichen Bestandteile einzeln und mit mehreren regulären Ausdrücken zu erfassen.&lt;/p>
&lt;h2 id="mehrere-reguläre-ausdrücke">Mehrere reguläre Ausdrücke&lt;/h2>
&lt;p>Anstatt alle Bestandteile in einem regulären Ausdruck zu erfassen,
kann man einen Text auch mit mehreren getrennten regulären Ausdrücken bearbeiten.&lt;/p>
&lt;p>&lt;strong>Code-Beispiel:&lt;/strong>&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="n">asig_regex&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="sa">r&lt;/span>&lt;span class="s2">&amp;#34;[A-Z]\d+[a-z]?&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">entity_definitions&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;NR&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">[&lt;/span>&lt;span class="sa">r&lt;/span>&lt;span class="s2">&amp;#34;^\d+[a-z]?&amp;#34;&lt;/span>&lt;span class="p">],&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;SIG&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">[&lt;/span>&lt;span class="sa">r&lt;/span>&lt;span class="s2">&amp;#34;HSTA.+(?=\()&amp;#34;&lt;/span>&lt;span class="p">],&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;ASIG&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">[&lt;/span>&lt;span class="sa">fr&lt;/span>&lt;span class="s2">&amp;#34;(?&amp;lt;=\()&lt;/span>&lt;span class="si">{&lt;/span>&lt;span class="n">asig_regex&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="s2">(?=\))&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="sa">fr&lt;/span>&lt;span class="s2">&amp;#34;(?&amp;lt;=, )&lt;/span>&lt;span class="si">{&lt;/span>&lt;span class="n">asig_regex&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="s2">(?=\))&amp;#34;&lt;/span>&lt;span class="p">],&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;VSIG&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">[&lt;/span>&lt;span class="sa">r&lt;/span>&lt;span class="s2">&amp;#34;(?&amp;lt;=Vorsignatur: ).+(?=,)&amp;#34;&lt;/span>&lt;span class="p">],&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;DATUM&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">[&lt;/span>&lt;span class="sa">r&lt;/span>&lt;span class="s2">&amp;#34;(?&amp;lt;=\) ).+$&amp;#34;&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">for&lt;/span> &lt;span class="n">text&lt;/span> &lt;span class="ow">in&lt;/span> &lt;span class="p">[&lt;/span>&lt;span class="n">text1&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">text2&lt;/span>&lt;span class="p">]:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">found&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">{}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">for&lt;/span> &lt;span class="n">key&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">regex_list&lt;/span> &lt;span class="ow">in&lt;/span> &lt;span class="n">entity_definitions&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">items&lt;/span>&lt;span class="p">():&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">for&lt;/span> &lt;span class="n">regex&lt;/span> &lt;span class="ow">in&lt;/span> &lt;span class="n">regex_list&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">match&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">re&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">search&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">regex&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">text&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="n">match&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">found&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="n">key&lt;/span>&lt;span class="p">]&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">match&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">group&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">found&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>&lt;strong>Ausgabe:&lt;/strong>&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="p">{&lt;/span>&lt;span class="s1">&amp;#39;NR&amp;#39;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s1">&amp;#39;42&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s1">&amp;#39;SIG&amp;#39;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s1">&amp;#39;HSTA L13 42 &amp;#39;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s1">&amp;#39;ASIG&amp;#39;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s1">&amp;#39;A9594&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s1">&amp;#39;DATUM&amp;#39;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s1">&amp;#39;1798&amp;#39;&lt;/span>&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">{&lt;/span>&lt;span class="s1">&amp;#39;NR&amp;#39;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s1">&amp;#39;113a&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s1">&amp;#39;SIG&amp;#39;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s1">&amp;#39;HSTA L13 50-55c &amp;#39;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s1">&amp;#39;ASIG&amp;#39;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s1">&amp;#39;T1234c&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s1">&amp;#39;VSIG&amp;#39;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s1">&amp;#39;GLAK B33 F 7 13b&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s1">&amp;#39;DATUM&amp;#39;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s1">&amp;#39;ca. 18. Jhd.&amp;#39;&lt;/span>&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Diese Methode ist aufwendiger in der Implementierung, jedoch deutlich flexibler als die Verwendung eines einzelnen regulären Ausdrucks.&lt;/p>
&lt;p>Aber auch hier zeigen sich schnell mehrere Probleme:&lt;/p>
&lt;ol>
&lt;li>Keine Warnung/Fehler, wenn sich reguläre Ausdrücke überlappen.&lt;/li>
&lt;li>Keine automatische Anpassung, wenn es mehrere Ergebnisse für ein Entity gibt.&lt;/li>
&lt;li>Keine Markierung von schon ausgewählten/extrahierten Informationen.&lt;/li>
&lt;/ol>
&lt;p>Dies lässt sich nachrüsten, sorgt jedoch für weitere Komplexität bei der Umsetzung.
Eine Lösung hierfür bieten Frameworks zur Extraktion von Informationen aus Text,
wobei wir spaCy für diesen Zweck einsetzen.&lt;/p>
&lt;h2 id="regelbasiertes-matching-mit-spacy">Regelbasiertes Matching mit spaCy&lt;/h2>
&lt;p>Das NLP Framework spaCy hat ein eigenes System für das &lt;a href="https://spacy.io/usage/rule-based-matching" target="_blank" rel="noopener">regelbasierte Matching&lt;/a>.&lt;/p>
&lt;p>Daher hier ein Beispiel mit einer &lt;a href="https://spacy.io/usage/processing-pipelines" target="_blank" rel="noopener">spaCy Pipeline&lt;/a>.&lt;/p>
&lt;p>&lt;strong>Code-Beispiel:&lt;/strong>&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="n">nlp&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">German&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">ruler&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">nlp&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">add_pipe&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;entity_ruler&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">patterns&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">[&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">{&lt;/span>&lt;span class="s2">&amp;#34;label&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;NR&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;id&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;nr&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;pattern&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">[{&lt;/span>&lt;span class="s2">&amp;#34;IS_SENT_START&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="kc">True&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;IS_DIGIT&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="kc">True&lt;/span>&lt;span class="p">}]},&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">{&lt;/span>&lt;span class="s2">&amp;#34;label&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;NR&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;id&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;nr&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;pattern&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">[&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">{&lt;/span>&lt;span class="s2">&amp;#34;IS_SENT_START&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="kc">True&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;TEXT&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">{&lt;/span>&lt;span class="s2">&amp;#34;REGEX&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="sa">r&lt;/span>&lt;span class="s2">&amp;#34;^\d+[a-z]?$&amp;#34;&lt;/span>&lt;span class="p">}}]},&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">{&lt;/span>&lt;span class="s2">&amp;#34;label&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;SIG&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;id&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;sig&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;pattern&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">[&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">{&lt;/span>&lt;span class="s2">&amp;#34;TEXT&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;HSTA&amp;#34;&lt;/span>&lt;span class="p">},&lt;/span> &lt;span class="p">{&lt;/span>&lt;span class="s2">&amp;#34;SHAPE&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;Xdd&amp;#34;&lt;/span>&lt;span class="p">},&lt;/span> &lt;span class="p">{&lt;/span>&lt;span class="s2">&amp;#34;TEXT&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">{&lt;/span>&lt;span class="s2">&amp;#34;REGEX&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="sa">r&lt;/span>&lt;span class="s2">&amp;#34;^\d+[a-z]?$&amp;#34;&lt;/span>&lt;span class="p">}},&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">{&lt;/span>&lt;span class="s2">&amp;#34;TEXT&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;-&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;OP&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;?&amp;#34;&lt;/span>&lt;span class="p">},&lt;/span> &lt;span class="p">{&lt;/span>&lt;span class="s2">&amp;#34;TEXT&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">{&lt;/span>&lt;span class="s2">&amp;#34;REGEX&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="sa">r&lt;/span>&lt;span class="s2">&amp;#34;^\d+[a-z]?$&amp;#34;&lt;/span>&lt;span class="p">},&lt;/span> &lt;span class="s2">&amp;#34;OP&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;?&amp;#34;&lt;/span>&lt;span class="p">}]},&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">{&lt;/span>&lt;span class="s2">&amp;#34;label&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;ASIG&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;id&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;asig&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;pattern&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">[{&lt;/span>&lt;span class="s2">&amp;#34;SHAPE&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;Xdddd&amp;#34;&lt;/span>&lt;span class="p">}]},&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">{&lt;/span>&lt;span class="s2">&amp;#34;label&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;ASIG&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;id&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;asig&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;pattern&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">[{&lt;/span>&lt;span class="s2">&amp;#34;SHAPE&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;Xddddx&amp;#34;&lt;/span>&lt;span class="p">}]},&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">{&lt;/span>&lt;span class="s2">&amp;#34;label&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;DATUM&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;id&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;date&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;pattern&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">[{&lt;/span>&lt;span class="s2">&amp;#34;SHAPE&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;dddd&amp;#34;&lt;/span>&lt;span class="p">}]},&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">{&lt;/span>&lt;span class="s2">&amp;#34;label&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;DATUM&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;id&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;date&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;pattern&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">[&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">{&lt;/span>&lt;span class="s2">&amp;#34;TEXT&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;ca.&amp;#34;&lt;/span>&lt;span class="p">},&lt;/span> &lt;span class="p">{&lt;/span>&lt;span class="s2">&amp;#34;SHAPE&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;dd.&amp;#34;&lt;/span>&lt;span class="p">},&lt;/span> &lt;span class="p">{&lt;/span>&lt;span class="s2">&amp;#34;TEXT&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;Jhd.&amp;#34;&lt;/span>&lt;span class="p">}]},&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">ruler&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">add_patterns&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">patterns&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">doc&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">nlp&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">text1&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">displacy&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">render&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">doc&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">style&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;ent&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;div class="entities" style="line-height: 2.5; direction: ltr">
&lt;mark class="entity" style="background: #b3e2cd; padding: 0.45em 0.6em; margin: 0 0.25em; line-height: 1; border-radius: 0.35em;">
42
&lt;span style="font-size: 0.8em; font-weight: bold; line-height: 1; border-radius: 0.35em; vertical-align: middle; margin-left: 0.5rem">NR&lt;/span>
&lt;/mark>
&lt;mark class="entity" style="background: #fdcdac; padding: 0.45em 0.6em; margin: 0 0.25em; line-height: 1; border-radius: 0.35em;">
HSTA L13 42
&lt;span style="font-size: 0.8em; font-weight: bold; line-height: 1; border-radius: 0.35em; vertical-align: middle; margin-left: 0.5rem">SIG&lt;/span>
&lt;/mark>
(
&lt;mark class="entity" style="background: #cbd5e8; padding: 0.45em 0.6em; margin: 0 0.25em; line-height: 1; border-radius: 0.35em;">
A9594
&lt;span style="font-size: 0.8em; font-weight: bold; line-height: 1; border-radius: 0.35em; vertical-align: middle; margin-left: 0.5rem">ASIG&lt;/span>
&lt;/mark>
)
&lt;mark class="entity" style="background: #e6f5c9; padding: 0.45em 0.6em; margin: 0 0.25em; line-height: 1; border-radius: 0.35em;">
1798
&lt;span style="font-size: 0.8em; font-weight: bold; line-height: 1; border-radius: 0.35em; vertical-align: middle; margin-left: 0.5rem">DATUM&lt;/span>
&lt;/mark>
&lt;/div>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="n">doc2&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">nlp&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">text2&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">displacy&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">render&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">doc2&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">style&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;ent&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;div class="entities" style="line-height: 2.5; direction: ltr">
&lt;mark class="entity" style="background: #b3e2cd; padding: 0.45em 0.6em; margin: 0 0.25em; line-height: 1; border-radius: 0.35em;">
113a
&lt;span style="font-size: 0.8em; font-weight: bold; line-height: 1; border-radius: 0.35em; vertical-align: middle; margin-left: 0.5rem">NR&lt;/span>
&lt;/mark>
&lt;mark class="entity" style="background: #fdcdac; padding: 0.45em 0.6em; margin: 0 0.25em; line-height: 1; border-radius: 0.35em;">
HSTA L13 50-55c
&lt;span style="font-size: 0.8em; font-weight: bold; line-height: 1; border-radius: 0.35em; vertical-align: middle; margin-left: 0.5rem">SIG&lt;/span>
&lt;/mark>
(Vorsignatur: GLAK B33 F 7 13b,
&lt;mark class="entity" style="background: #cbd5e8; padding: 0.45em 0.6em; margin: 0 0.25em; line-height: 1; border-radius: 0.35em;">
T1234c
&lt;span style="font-size: 0.8em; font-weight: bold; line-height: 1; border-radius: 0.35em; vertical-align: middle; margin-left: 0.5rem">ASIG&lt;/span>
&lt;/mark>
)
&lt;mark class="entity" style="background: #e6f5c9; padding: 0.45em 0.6em; margin: 0 0.25em; line-height: 1; border-radius: 0.35em;">
ca. 18. Jhd.
&lt;span style="font-size: 0.8em; font-weight: bold; line-height: 1; border-radius: 0.35em; vertical-align: middle; margin-left: 0.5rem">DATUM&lt;/span>
&lt;/mark>
&lt;/div>
&lt;p>Bei diesem Code-Beispiel sehen wir einige Vorteile bei der Verwendung von spaCy.
Wir können die mitgelieferten &lt;a href="https://spacy.io/usage/visualizers#ent" target="_blank" rel="noopener">Visualisierungstools&lt;/a> verwenden, mehrere Regeln für ein Entity hinterlegen und auf weniger komplexe Regeln zurückgreifen (Shape-Pattern, &lt;code>IS_PUNCT&lt;/code>, &amp;hellip;).&lt;/p>
&lt;p>Wir können uns auch direkt die übersprungenen Teile ausgeben lassen (oder sie markieren).&lt;/p>
&lt;p>&lt;strong>Code-Beispiel:&lt;/strong>&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="nb">print&lt;/span>&lt;span class="p">([&lt;/span>&lt;span class="n">token&lt;/span> &lt;span class="k">for&lt;/span> &lt;span class="n">token&lt;/span> &lt;span class="ow">in&lt;/span> &lt;span class="n">doc2&lt;/span> &lt;span class="k">if&lt;/span> &lt;span class="ow">not&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">token&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">ent_type_&lt;/span> &lt;span class="ow">or&lt;/span> &lt;span class="n">token&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">is_punct&lt;/span>&lt;span class="p">)])&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>&lt;strong>Ausgabe:&lt;/strong>&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="p">[&lt;/span>&lt;span class="n">Vorsignatur&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">GLAK&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">B33&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">F&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">7&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">13&lt;/span>&lt;span class="n">b&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Hier zeigen sich auch gleich mehrere Probleme bei der Verwendung von regelbasiertem Matching mit spaCy:&lt;/p>
&lt;ol>
&lt;li>Jedes Muster passt immer nur auf einen Token.&lt;/li>
&lt;li>Ein &amp;ldquo;lookahead&amp;rdquo; oder &amp;ldquo;lookbehind&amp;rdquo; wie bei regulären Ausdrücken ist (noch) nicht möglich.
Es gibt also keine Entsprechung für &lt;code>(?&amp;lt;=Vorsignatur: )[^,]+(?=,)&lt;/code>.&lt;/li>
&lt;/ol>
&lt;p>Um trotzdem nur die Vorsignatur zu extrahieren, ohne das Prefix &amp;ldquo;Vorsignatur: &amp;quot; mitzuspeichern, gibt es mehrere Lösungen:&lt;/p>
&lt;ol>
&lt;li>Nachbearbeitung der Entities, also das Prefix in einem separaten Durchlauf löschen.&lt;/li>
&lt;li>Die komplexen Muster in einem separaten Durchlauf verarbeiten (nächster Abschnitt).&lt;/li>
&lt;li>Reguläre Ausdrücke (Gesamttext) mit spaCy kombinieren (übernächster Abschnitt).&lt;/li>
&lt;/ol>
&lt;h2 id="erweitertes-regelbasiertes-matching-mit-spacy">Erweitertes regelbasiertes Matching mit spaCy&lt;/h2>
&lt;p>Für das folgende Beispiel wollen wir ein Entity basierend auf &amp;ldquo;Umgebungsinformationen&amp;rdquo; bestimmen.
Nehmen wir zum Beispiel an, dass es ziemlich komplex ist die Signatur zu bestimmen, wir aber wissen, dass die Signatur immer nach der Findbuch-Nr zu finden ist.&lt;/p>
&lt;p>Also würden wir gerne ein Muster der Form &lt;code>(?&amp;lt;=NR).+(?=\()&lt;/code>definieren.
Dafür verarbeiten wir den ersten Beispielsatz zweimal mit spaCy.&lt;/p>
&lt;p>Zuerst erstellen wir wieder eine Pipeline, die uns die &amp;ldquo;einfachen&amp;rdquo; Entities markiert.&lt;/p>
&lt;p>&lt;strong>Code-Beispiel:&lt;/strong>&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="n">nlp&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">German&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">ruler&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">nlp&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">add_pipe&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;entity_ruler&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">patterns&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">[{&lt;/span>&lt;span class="s2">&amp;#34;label&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;NR&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;pattern&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">[{&lt;/span>&lt;span class="s2">&amp;#34;IS_SENT_START&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="kc">True&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;IS_DIGIT&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="kc">True&lt;/span>&lt;span class="p">}]}]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">ruler&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">add_patterns&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">patterns&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">doc&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">nlp&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">text1&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">displacy&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">render&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">doc&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">style&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;ent&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;div class="entities" style="line-height: 2.5; direction: ltr">
&lt;mark class="entity" style="background: #b3e2cd; padding: 0.45em 0.6em; margin: 0 0.25em; line-height: 1; border-radius: 0.35em;">
42
&lt;span style="font-size: 0.8em; font-weight: bold; line-height: 1; border-radius: 0.35em; vertical-align: middle; margin-left: 0.5rem">NR&lt;/span>
&lt;/mark>
HSTA L13 42 (A9594) 1798&lt;/div>
&lt;p>Anschließend verarbeiten wir den mit Markierungen versehenen Beispielsatz mit einem &lt;code>Matcher&lt;/code> und unserem komplexen Muster.&lt;/p>
&lt;p>&lt;strong>Code-Beispiel:&lt;/strong>&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="n">matcher&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">Matcher&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">nlp&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">vocab&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">signature_pattern&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">[&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">{&lt;/span>&lt;span class="s2">&amp;#34;ENT_TYPE&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;NR&amp;#34;&lt;/span>&lt;span class="p">},&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">{&lt;/span>&lt;span class="s2">&amp;#34;TEXT&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">{&lt;/span>&lt;span class="s2">&amp;#34;NOT_IN&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">[&lt;/span>&lt;span class="s2">&amp;#34;(&amp;#34;&lt;/span>&lt;span class="p">]},&lt;/span> &lt;span class="s2">&amp;#34;OP&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;+&amp;#34;&lt;/span>&lt;span class="p">},&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">{&lt;/span>&lt;span class="s2">&amp;#34;TEXT&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;(&amp;#34;&lt;/span>&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">matcher&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">add&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;Signature&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="p">[&lt;/span>&lt;span class="n">signature_pattern&lt;/span>&lt;span class="p">])&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">matches&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">matcher&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">doc&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">for&lt;/span> &lt;span class="n">_&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">start&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">end&lt;/span> &lt;span class="ow">in&lt;/span> &lt;span class="n">matches&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">entity&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">Span&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">doc&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">start&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">end&lt;/span> &lt;span class="o">-&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">label&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;SIG&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">doc&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">ents&lt;/span> &lt;span class="o">+=&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">entity&lt;/span>&lt;span class="p">,)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">displacy&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">render&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">doc&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">style&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;ent&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;div class="entities" style="line-height: 2.5; direction: ltr">
&lt;mark class="entity" style="background: #b3e2cd; padding: 0.45em 0.6em; margin: 0 0.25em; line-height: 1; border-radius: 0.35em;">
42
&lt;span style="font-size: 0.8em; font-weight: bold; line-height: 1; border-radius: 0.35em; vertical-align: middle; margin-left: 0.5rem">NR&lt;/span>
&lt;/mark>
&lt;mark class="entity" style="background: #fdcdac; padding: 0.45em 0.6em; margin: 0 0.25em; line-height: 1; border-radius: 0.35em;">
HSTA L13 42
&lt;span style="font-size: 0.8em; font-weight: bold; line-height: 1; border-radius: 0.35em; vertical-align: middle; margin-left: 0.5rem">SIG&lt;/span>
&lt;/mark>
(A9594) 1798&lt;/div>
&lt;p>Hier erstellen wir das Entity selbst und fügen es den von spaCy verwalteten Informationen hinzu.
Der gefundene Treffer beinhaltet das Entity &lt;code>NR&lt;/code> und die öffnende Klammer &lt;code>(&lt;/code>,
daher schneiden wir noch vorne und hinten jeweils einen Token ab.&lt;/p>
&lt;p>Im ersten Durchlauf für die &lt;code>Nr&lt;/code> hat die Pipeline Komponente diese Aufgaben übernommen.&lt;/p>
&lt;div class="alert alert-note">
&lt;div>
&lt;strong>Hinweis:&lt;/strong> leider beinhalten die Treffer keinen Hinweis auf die Regel, die den Treffer erzeugt haben.
Hat man viele Regeln, die mit unterschiedlichen Labels oder Beschnitt versehen werden sollen, empfehlen sich
entweder der &lt;a href="https://spacy.io/usage/rule-based-matching#on_match" target="_blank" rel="noopener">on_match Callback&lt;/a> für die Regeln,
oder eine &lt;a href="https://spacy.io/usage/processing-pipelines#custom-components" target="_blank" rel="noopener">Custom Component&lt;/a> für die Pipeline.
&lt;/div>
&lt;/div>
&lt;h2 id="kombiniere-reguläre-ausdrücke-mit-spacy">Kombiniere reguläre Ausdrücke mit spaCy&lt;/h2>
&lt;p>Die Ansätze mit regulären Ausdrücken auf dem Gesamttext und dem regelbasierten Matching mit spaCy lassen sich auch kombinieren.
Zuerst lassen wir das Dokument von spaCy analysieren.
Anschließend wenden wir die regulären Ausdrücke auf den Gesamttext an und ermitteln die Position der Treffer.
Mit dieser Information erzeugen wir dann Entities mit spaCy.&lt;/p>
&lt;p>&lt;strong>Code-Beispiel:&lt;/strong>&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="n">nlp&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">German&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">ruler&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">nlp&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">add_pipe&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;entity_ruler&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">patterns&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">[&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">{&lt;/span>&lt;span class="s2">&amp;#34;label&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;NR&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;id&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;nr&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;pattern&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">[{&lt;/span>&lt;span class="s2">&amp;#34;IS_SENT_START&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="kc">True&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;IS_DIGIT&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="kc">True&lt;/span>&lt;span class="p">}]}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">ruler&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">add_patterns&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">patterns&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">doc&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">nlp&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">text1&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">displacy&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">render&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">doc&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">style&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;ent&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;div class="entities" style="line-height: 2.5; direction: ltr">
&lt;mark class="entity" style="background: #b3e2cd; padding: 0.45em 0.6em; margin: 0 0.25em; line-height: 1; border-radius: 0.35em;">
42
&lt;span style="font-size: 0.8em; font-weight: bold; line-height: 1; border-radius: 0.35em; vertical-align: middle; margin-left: 0.5rem">NR&lt;/span>
&lt;/mark>
HSTA L13 42 (A9594) 1798&lt;/div>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="n">entity_definitions&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">{&lt;/span>&lt;span class="s2">&amp;#34;DATUM&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="sa">r&lt;/span>&lt;span class="s2">&amp;#34;(?&amp;lt;=\) ).+$&amp;#34;&lt;/span>&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">for&lt;/span> &lt;span class="n">key&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">regex&lt;/span> &lt;span class="ow">in&lt;/span> &lt;span class="n">entity_definitions&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">items&lt;/span>&lt;span class="p">():&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">match&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">re&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">search&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">regex&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">doc&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">text&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="n">match&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">start&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">end&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">match&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">span&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">entity&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">doc&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">char_span&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">start&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">end&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">label&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="n">key&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">doc&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">ents&lt;/span> &lt;span class="o">+=&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">entity&lt;/span>&lt;span class="p">,)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">displacy&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">render&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">doc&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">style&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;ent&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;div class="entities" style="line-height: 2.5; direction: ltr">
&lt;mark class="entity" style="background: #b3e2cd; padding: 0.45em 0.6em; margin: 0 0.25em; line-height: 1; border-radius: 0.35em;">
42
&lt;span style="font-size: 0.8em; font-weight: bold; line-height: 1; border-radius: 0.35em; vertical-align: middle; margin-left: 0.5rem">NR&lt;/span>
&lt;/mark>
HSTA L13 42 (A9594)
&lt;mark class="entity" style="background: #e6f5c9; padding: 0.45em 0.6em; margin: 0 0.25em; line-height: 1; border-radius: 0.35em;">
1798
&lt;span style="font-size: 0.8em; font-weight: bold; line-height: 1; border-radius: 0.35em; vertical-align: middle; margin-left: 0.5rem">DATUM&lt;/span>
&lt;/mark>
&lt;/div>
&lt;p>Ein ähnliches Beispiel dazu findet sich auch in der &lt;a href="https://spacy.io/usage/rule-based-matching#regex-text" target="_blank" rel="noopener">spaCy Dokumentation&lt;/a>.&lt;/p>
&lt;p>Hier sind noch die folgenden Dinge zu beachten:&lt;/p>
&lt;ol>
&lt;li>Es werden keine Entities überschrieben.&lt;/li>
&lt;li>Es können keine sich überschneidenden Entities angelegt werden.&lt;/li>
&lt;li>Manchmal &amp;ldquo;rutschen&amp;rdquo; Trennzeichen (z.B. Leerzeichen) mit in den Beginn oder das Ende der Treffer. Diese führen beim Setzen einer Entity in spaCy zu einem Fehler.&lt;/li>
&lt;/ol>
&lt;p>Die entsprechenden Fehlerbehandlungen haben wir im Code-Beispiel ausgelassen.&lt;/p>
&lt;h2 id="fazit">Fazit&lt;/h2>
&lt;p>Bei der Aufbereitung von Findbüchern für die Datenbank sind wir sowohl mit regulären Ausdrücken, als auch mit dem Regelsystem von spaCy an die jeweiligen Grenzen der Technologie gestoßen.
Dabei haben wir die Toolunterstützung von spaCy zu schätzen gelernt, die uns einiges an Entwicklungsaufwand abnimmt und bei der Visualisierung der Ergebnisse unterstützt.&lt;/p>
&lt;p>Mit einer Kombination aus regulären Ausdrücken und Regeln in spaCy, die auf schon identifizierten Entities basieren,
konnten wir mit einer übersichtlichen Codebasis selbst komplexe Datenaufbereitungen durchführen.&lt;/p></description></item><item><title>Wie wir gedruckte Findbücher in unsere Datenbank bekommen, ohne zu viel Zeit in manuelle Arbeiten zu investieren</title><link>https://fdmlab.landesarchiv-bw.de/post/2021-06-wie-wir-gedruckte-findbuecher-in-unsere-datenbank-bekommen/</link><pubDate>Tue, 15 Jun 2021 00:00:00 +0000</pubDate><guid>https://fdmlab.landesarchiv-bw.de/post/2021-06-wie-wir-gedruckte-findbuecher-in-unsere-datenbank-bekommen/</guid><description>&lt;p>Viele Archive kennen diese Situation: Es gibt ein archivisches Fachinformationssystem (AFIS), über das Archivgut erschlossen und für eine Online-Recherche bereitgestellt wird. Doch gleichzeitig existiert zu einigen Beständen auch noch eine Reihe älterer gedruckter Findbücher im Lesesaal. Diese Bestände können nicht in der Datenbank recherchiert werden.&lt;/p>
&lt;p>Um für diese Bestände zeitgemäße Recherchemöglichkeiten bieten zu können, müssen die Erschließungsinformationen aus den analogen Findbüchern in das digitale Fachinformationssystem übertragen werden. Wie geht das, ohne dass Archivar*innen zu viel wertvolle Arbeitszeit in manuelle Arbeitsschritte investieren? In diesem Beitrag zeigen wir an einem Beispiel, wie wir dieses Problem im FDMLab angegangen sind und was wir dabei gelernt haben.&lt;/p>
&lt;h2 id="der-prozess">Der Prozess&lt;/h2>
&lt;div class="mermaid">---
title: Findbuch Extraktionsprozess
config:
look: handDrawn
theme: neutral
---
flowchart LR
A[Findbuch]
--> |OCR| B[Word]
--> |Textexport| C[Text]
--> |Daten Transformation| D[CSV]
--> |Import| E[(AFIS)]
&lt;/div>
&lt;p>Überblick über unseren Prozess, es folgen die einzelnen Bearbeitungsschritte im Detail.&lt;/p>
&lt;h3 id="findbuch-digitalisieren-und-volltexterkennung-durchführen">Findbuch digitalisieren und Volltexterkennung durchführen&lt;/h3>
&lt;div class="mermaid">---
title: Prozess: OCR
config:
look: handDrawn
theme: neutral
---
flowchart LR
A[Findbuch]
--> |OCR| B[Word]
&lt;/div>
&lt;p>Im FDMLab wollen wir das Findbuch „Fürstlich Thurn und Taxissches Archiv Obermarchtal Grafschaft Friedberg-Scheer“&lt;sup id="fnref:1">&lt;a href="#fn:1" class="footnote-ref" role="doc-noteref">1&lt;/a>&lt;/sup> bearbeiten, das 1.517 Urkunden des 14. bis 19. Jahrhunderts enthält. Das Findbuch wurde im Vorfeld digitalisiert und es wurde eine Volltexterkennung mittels OCR durchgeführt. Das Ergebnis hat das FDMLab in Form einer docx-Datei erhalten.&lt;/p>
&lt;h3 id="extraktion-der-erschließungsdaten">Extraktion der Erschließungsdaten&lt;/h3>
&lt;div class="mermaid">---
title: Prozess: Textexport
config:
look: handDrawn
theme: neutral
---
flowchart LR
B[Word]
--> |Textexport| C[Text]
&lt;/div>
&lt;p>Ziel ist es nun, die Daten in ein maschinenlesbares Format umzuwandeln, das wir später in unser AFIS importieren können. Hierfür wandeln wir die Datei in eine txt-Datei um.&lt;/p>
&lt;p>Die docx-Datei ist aus zwei Gründen nicht für die weitere automatische Verarbeitung der Daten geeignet:&lt;/p>
&lt;ol>
&lt;li>Word &lt;em>verwendet&lt;/em> schwebende Felder, um manchen Text so zu platzieren, wie er vermeintlich im Original vorlag. Diese Felder müssen in der Struktur des XML-Dokuments erstmal gefunden und dann deren Position im Text separat berechnet werden. Daher ist es einfacher, mit dem Reintext zu arbeiten, in dem der Text schon &amp;ldquo;richtig&amp;rdquo; formatiert ist.&lt;/li>
&lt;li>Word hat einige Findbuchnummern und Datumsangaben als Aufzählfelder deklariert. Eine manuelle Korrektur oder Veränderung eines solchen Feldes (z.B. wegen OCR oder Layoutproblemen) kann unerwartete Seiteneffekte haben. Beispielsweise wird in so einem Fall beim Einfügen einer Leerzeile von Word automatisch eine Findbuchnummer mehrere Seiten später hochgezählt.&lt;/li>
&lt;/ol>
&lt;div class="alert alert-note">
&lt;div>
&lt;p>Es hat sich bewährt, eine Ausgabe des analogen Findbuchs stets zur Hand zu haben, um&lt;/p>
&lt;ul>
&lt;li>fehlende/fehlerhafte Abschnitte korrigieren zu können,&lt;/li>
&lt;li>Kürzel verstehen und auflösen zu können,&lt;/li>
&lt;li>Validitätschecks (Anzahl Einträge, &amp;hellip;) durchführen zu können.&lt;/li>
&lt;/ul>
&lt;/div>
&lt;/div>
&lt;div class="mermaid">---
title: Prozess: Daten Transformation
config:
look: handDrawn
theme: neutral
---
flowchart LR
C[Text]
--> |Daten Transformation| D[CSV]
&lt;/div>
&lt;p>Aus der txt-Datei können mit Verfahren der automatischen Textextraktion die verschiedenen Findbucheinträge aus dem Gesamtdokument separiert und die einzelnen Erschließungsdaten wie Titel, Datierung, Signatur etc. extrahiert werden. Die extrahierten Daten werden in eine csv-Datei geschrieben, da sich das csv-Format für den Import in das AFIS eignet.&lt;/p>
&lt;p>In diesem Projekt haben wir ausschließlich sogenannte reguläre Ausdrücke verwendet, um Muster zur Datenextraktion zu definieren.
Mit dem regulären Ausdruck &lt;code>\d{4}(-\d{2}){0,2}&lt;/code> lässt sich zum Beispiel ein Datum in der Form &lt;code>2020&lt;/code>, &lt;code>2020-03&lt;/code> oder &lt;code>2020-03-28&lt;/code> erkennen.
Auf Details werden wir in separaten Artikeln nochmal eingehen.&lt;/p>
&lt;h3 id="import-der-erschließungsdaten-ins-afis">Import der Erschließungsdaten ins AFIS&lt;/h3>
&lt;div class="mermaid">---
title: Prozess: Import
config:
look: handDrawn
theme: neutral
---
flowchart LR
D[CSV]
--> |Import| E[(AFIS)]
&lt;/div>
&lt;p>Die csv-Datei enthält die Erschließungsdaten in einem strukturierten, maschinenlesbaren Format. Sie kann mit einem Übernahmeassistenten verarbeitet werden, der einen automatischen Import der Daten in das AFIS ermöglicht.&lt;/p>
&lt;p>War bis hierher technisches Wissen gefragt, braucht es nun archivarische Expertise, denn im nächsten Schritt geht es um das Mapping der extrahierten Daten mit den Datenfeldern im Erschließungsformular für Urkunden. Nachdem die csv-Datei ausgelesen und das Mapping im Übernahmeassistenten vorgenommen wurden, können die Daten in einem Arbeitsgang in das AFIS importiert und unter einem zuvor definierten Punkt in der Tektonik eingehängt werden.&lt;/p>
&lt;h3 id="freischalten-der-erschließungsdaten-für-die-online-recherche">Freischalten der Erschließungsdaten für die Online-Recherche&lt;/h3>
&lt;p>Die Erschließungsdaten können jetzt an das &lt;a href="https://www2.landesarchiv-bw.de/ofs21/home.php" target="_blank" rel="noopener">Online-Findmittelsystem&lt;/a> (OLF) des LABW übertragen und für die Internetrecherche freigeschaltet werden. Nutzer*innen können nun online nach Urkunden der Grafschaft Friedberg-Scheer recherchieren und müssen nicht mehr auf die Printversion des Findbuchs zurückgreifen.&lt;/p>
&lt;h2 id="lessons-learned">Lessons Learned&lt;/h2>
&lt;p>Nach der Bearbeitung des Findbuchs können wir die folgenden Punkte als Lessons Learned mitnehmen:&lt;/p>
&lt;ol>
&lt;li>Die automatische Textextraktion stellt ein geeignetes Verfahren für die Automatisierung der Übertragung von Findbüchern in die archivische Datenbank dar. Trotzdem gab es nach wie vor noch manuelle Nacharbeiten. Dies resultiert u.a. daraus, dass das gedruckte Findbuch zwar auf den ersten Blick eine normierte Form besitzt, bei näherem Hinsehen aber verschiedene Unregelmäßigkeiten bei Struktur, Layout und auch sprachlicher Gestaltung der Findbucheinträge sichtbar werden, die die Formulierung von Extraktionsregeln erschweren.&lt;/li>
&lt;li>Word ist als Dateiformat für die Datenextraktion ungeeignet. Da das Layout bei der Datenextraktion relevant ist, sollte, wenn möglich, direkt mit Bilddateien und reinen Textdateien (txt) gearbeitet werden &lt;sup id="fnref:2">&lt;a href="#fn:2" class="footnote-ref" role="doc-noteref">2&lt;/a>&lt;/sup>.&lt;/li>
&lt;li>Bei der Findbuchextraktion ist eine enge Zusammenarbeit von technischem und archivfachlichem Personal empfehlenswert. Durch die Zusammenarbeit kann die Granularität der Datenextraktion schneller bestimmt und die anschließende Abbildung der extrahierten Daten auf das Erfassungsformular frustfrei durchgeführt werden.&lt;/li>
&lt;/ol>
&lt;div class="footnotes" role="doc-endnotes">
&lt;hr>
&lt;ol>
&lt;li id="fn:1">
&lt;p>Dep. 30/1 T1 Fürstlich Thurn und Taxissches Archiv Obermarchtal Grafschaft Friedberg-Scheer. Urkundenregesten 1304-1802. Bearb. Von Robert Kretzschmar. Stuttgart 1993 (Inventare der nichtstaatlichen Archive in Baden-Württemberg ; Bd. 18), &lt;a href="https://www2.landesarchiv-bw.de/ofs21/olf/struktur.php?bestand=2240&amp;amp;klassi=001" target="_blank" rel="noopener">Online-Version&lt;/a> des gedruckten Inventars.&amp;#160;&lt;a href="#fnref:1" class="footnote-backref" role="doc-backlink">&amp;#x21a9;&amp;#xfe0e;&lt;/a>&lt;/p>
&lt;/li>
&lt;li id="fn:2">
&lt;p>Die &lt;strong>digitale&lt;/strong> Druckvorlage ist natürlich noch besser geeignet.&amp;#160;&lt;a href="#fnref:2" class="footnote-backref" role="doc-backlink">&amp;#x21a9;&amp;#xfe0e;&lt;/a>&lt;/p>
&lt;/li>
&lt;/ol>
&lt;/div></description></item></channel></rss>