aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/eu
diff options
context:
space:
mode:
authorMatthias Andreas Benkard <code@mail.matthias.benkard.de>2026-08-24 21:32:26 +0200
committerMatthias Andreas Benkard <code@mail.matthias.benkard.de>2026-08-24 21:32:26 +0200
commit751860690d2b74252ba3126d51cd37aa1c9ed0eb (patch)
tree60a6040602bfd0f62410eb6aaf9bb7ae7ea05d8f /src/main/java/eu
parente8213085ebb446081cfe6ce45f047d6862e1a755 (diff)
Rheinland-Pfalz schreibt Worte, nicht Wörter
Die Erste Landesverordnung zur Änderung der Ausbildungs- und Prüfungsordnung der Unfallkasse (GVBl. 2026 Nr. 21) kommt als Erkennungsfall in den Bestand — nicht als Akzeptanzfall, und der Grund liegt in der Quelle: Das rheinland-pfälzische Landesrechtsportal führt keine früheren Gesamtausgaben, ebensowenig das saarländische und das sachsen-anhaltische. Die Fassungsliste, über die Hessen, Schleswig-Holstein, Berlin und Baden-Württemberg jede Fassung datierbar ausgeben, gibt es dort nicht. Ohne Vorfassung kein Vergleich; der Stamm ist hier die Nachfassung, und die neun „Zieltext nicht vorhanden“ sind gerade der Beleg dafür, dass die Befehle dort bereits vollzogen sind. Zwei allgemeine Funde hat der Fall trotzdem gebracht. Das Land schreibt „die Worte“, wo das Handbuch der Rechtsförmlichkeit „die Wörter“ setzt — der Erkenner nimmt die Nebenform jetzt überall an, ohne sie blieben sieben der 23 Befehle unerkannt. Und der Seitenfuß des dortigen Gesetzblattes steht im Inhaltsstrom und zerschneidet das Zitat einer Neufassung („§ 18 erhält folgende Fassung:“ / Fußzeile / „„§ 18 …““); er wird nun herausgeschnitten wie die Füße der Gesetzblätter Berlins, Thüringens und Baden-Württembergs. Drei Idiome bleiben benannt offen: die Satzzeichen-Ersetzung im Verbund mit einer Halbsatz-Anfügung („durch einen Strichpunkt ersetzt und folgender Halbsatz angefügt“), „In der Einleitung“ als Ziel, und die Verweisung auf einen anderen Punkt („entsprechend der vorstehenden Nummer 8 Buchst. a“). Nebenbei ein besserer Beschaffungsweg, in RheinlandPfalz/SOURCES festgehalten: Der Portaltext wird im Browser als Blob zum Herunterladen angeboten und landet unmittelbar als Datei im Dateisystem, statt stückweise durch die Textausgabe der Browsersteuerung zu gehen. Der PDF-Verweis der Dokumentansicht taugt dafür nicht — er ist an die Sitzung gebunden. Geprüft: 350 Tests, REUSE 188/188. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Change-Id: I317f2d368b734c1152cd47cc09356de60f5dfb35
Diffstat (limited to 'src/main/java/eu')
-rw-r--r--src/main/java/eu/mulk/aendggner/aenderung/parse/BefehlErkenner.java33
-rw-r--r--src/main/java/eu/mulk/aendggner/aenderung/parse/TextBereiniger.java11
2 files changed, 28 insertions, 16 deletions
diff --git a/src/main/java/eu/mulk/aendggner/aenderung/parse/BefehlErkenner.java b/src/main/java/eu/mulk/aendggner/aenderung/parse/BefehlErkenner.java
index 122fb6b..967fa0f 100644
--- a/src/main/java/eu/mulk/aendggner/aenderung/parse/BefehlErkenner.java
+++ b/src/main/java/eu/mulk/aendggner/aenderung/parse/BefehlErkenner.java
@@ -46,7 +46,7 @@ final class BefehlErkenner {
// Wiederkehrende Bausteine.
private static final String WOERTER =
- "(?:die Wörter|das Wort|die Angabe|die Zahl|die Verweisung)";
+ "(?:die (?:Wörter|Worte)|das Wort|die Angabe|die Zahl|die Verweisung)";
private static final String Z = "«(\\d+)»";
// Der Doppelpunkt fehlt gelegentlich (Seitenumbruch-Artefakt); für einen Punkt mit Unterpunkten
@@ -138,7 +138,7 @@ final class BefehlErkenner {
// darf auch hier verkürzt sein („Die Angabe „X“ wird durch „Y“ ersetzt“, hessisches GVBl).
private static final Pattern ERSETZUNG_OHNE_STELLE =
Pattern.compile(
- "^(?:Die Wörter|Das Wort|Die Angabe|Die Zahl|Die Verweisung) "
+ "^(?:Die (?:Wörter|Worte)|Das Wort|Die Angabe|Die Zahl|Die Verweisung) "
+ Z
+ " (?:wird|werden) (jeweils )?durch (?:"
+ WOERTER
@@ -152,7 +152,7 @@ final class BefehlErkenner {
private static final Pattern ERSETZUNG_MIT_ANKER =
Pattern.compile(
"^(?:In )?(.+?) (?:wird|werden) (?:jeweils )?nach "
- + "(?:dem Wort|den Wörtern|der Angabe|der Zahl|der Verweisung) "
+ + "(?:dem Wort|den (?:Wörtern|Worten)|der Angabe|der Zahl|der Verweisung) "
+ Z
+ " "
+ WOERTER
@@ -168,7 +168,7 @@ final class BefehlErkenner {
private static final Pattern WORT_VORANSTELLUNG =
Pattern.compile(
"^(?:In )?(.+?) (?:wird|werden) (?:jeweils )?"
- + "(?:dem Wort|den Wörtern|der Angabe|der Zahl|der Verweisung) "
+ + "(?:dem Wort|den (?:Wörtern|Worten)|der Angabe|der Zahl|der Verweisung) "
+ Z
+ " "
+ WOERTER
@@ -224,7 +224,7 @@ final class BefehlErkenner {
private static final Pattern WOERTER_EINFUEGUNG =
Pattern.compile(
"^(?:In )?(.+?) (?:wird|werden) (?:jeweils )?(nach|vor) "
- + "(?:dem Wort|den Wörtern|der Angabe|der Zahl|der Verweisung) "
+ + "(?:dem Wort|den (?:Wörtern|Worten)|der Angabe|der Zahl|der Verweisung) "
+ Z
+ " "
+ WOERTER
@@ -257,7 +257,7 @@ final class BefehlErkenner {
// statt einer Stellenangabe; das Ziel selbst erbt der Befehl aus dem Kontextrahmen.
private static final Pattern STRUKTUR_EINFUEGUNG_WORTANKER =
Pattern.compile(
- "^(Nach|Vor) (?:dem Wort|den Wörtern|der Angabe|der Zahl) "
+ "^(Nach|Vor) (?:dem Wort|den (?:Wörtern|Worten)|der Angabe|der Zahl) "
+ Z
+ " (?:wird|werden) (?:der |die |das )?folgende[nrs]? (?:neue[nrs]? )?(.+?) "
+ "(?:ein|an)gefügt: "
@@ -402,7 +402,7 @@ final class BefehlErkenner {
// allem als rechte Klausel eines Verbunds auf („… ersetzt und die Angabe „X“ wird gestrichen“).
private static final Pattern STREICHUNG_OHNE_STELLE =
Pattern.compile(
- "^(?:Die Wörter|Das Wort|Die Angabe|Die Zahl|Die Verweisung) "
+ "^(?:Die (?:Wörter|Worte)|Das Wort|Die Angabe|Die Zahl|Die Verweisung) "
+ Z
+ " (?:wird|werden) "
+ "(?:jeweils )?gestrichen\\.$");
@@ -479,7 +479,7 @@ final class BefehlErkenner {
private static final Pattern KOMMA_UND_WOERTER_EINFUEGUNG =
Pattern.compile(
"^(?:In )?(.+?) (?:wird|werden) (?:jeweils )?(nach|vor) "
- + "(?:dem Wort|den Wörtern|der Angabe|der Zahl|der Verweisung) "
+ + "(?:dem Wort|den (?:Wörtern|Worten)|der Angabe|der Zahl|der Verweisung) "
+ Z
// Das wiederholte Verb fehlt im amtlichen Satz oft („… ein Komma und die Angabe „…“
// eingefügt“, GV. NRW.).
@@ -545,7 +545,8 @@ final class BefehlErkenner {
+ "$");
// Paare trennen sich an „ und “/„ sowie “ sowie an Kommata vor dem nächsten Wörter-Objekt.
private static final Pattern PAAR_SEP =
- Pattern.compile(" und | sowie |,\\s+(?=(?:die Wörter|das Wort|die Angabe|die Zahl) )");
+ Pattern.compile(
+ " und | sowie |,\\s+(?=(?:die (?:Wörter|Worte)|das Wort|die Angabe|die Zahl) )");
// „Die bisherigen Absätze 6 und 7 werden die Absätze 1 und 2.“ — koordinierte Umnummerierung.
private static final Pattern UMNUMMERIERUNG_KOORDINIERT =
@@ -576,7 +577,7 @@ final class BefehlErkenner {
Pattern.compile("(?: und | sowie |,\\s+)(?=nach |vor )");
private static final Pattern EIN_EINFUEGUNGS_PAAR =
Pattern.compile(
- "^(nach|vor) (?:dem Wort|den Wörtern|der Angabe|der Zahl) "
+ "^(nach|vor) (?:dem Wort|den (?:Wörtern|Worten)|der Angabe|der Zahl) "
+ Z
+ " (?:(ein Komma und )?(?:wird |werden )?"
+ WOERTER
@@ -593,7 +594,7 @@ final class BefehlErkenner {
// Komma-Kette gleichrangiger Klauseln („… ersetzt, die Angabe «n» wird gestrichen
// und …“) — nur vor einer Wortgruppen-Klausel mit maskiertem Zitat, damit echte
// Relativsätze nicht getrennt werden.
- + "|, (?=(?:die Wörter|das Wort|die Angabe|die Zahl) «)"
+ + "|, (?=(?:die (?:Wörter|Worte)|das Wort|die Angabe|die Zahl) «)"
// Ebenso vor einer Satzzeichen-Klausel („… ersetzt, der Punkt am Ende durch ein
// Semikolon ersetzt und …“).
+ "|, (?=(?:der Punkt|das Komma|das Semikolon) am Ende)");
@@ -619,7 +620,7 @@ final class BefehlErkenner {
private static final Pattern KOMMA_EINFUEGUNG =
Pattern.compile(
"^(?:In )?(.+?) (?:wird|werden) (?:jeweils )?(nach|vor) "
- + "(?:dem Wort|den Wörtern|der Angabe|der Zahl|der Verweisung) "
+ + "(?:dem Wort|den (?:Wörtern|Worten)|der Angabe|der Zahl|der Verweisung) "
+ Z
+ " (ein Komma|ein Semikolon|einen Punkt) eingefügt\\.$");
@@ -627,7 +628,7 @@ final class BefehlErkenner {
// den Kontext). Tritt vor allem als rechte Klausel eines Verbundbefehls auf.
private static final Pattern EINFUEGUNG_ANKER_ZUERST =
Pattern.compile(
- "^(Nach|Vor) (?:dem Wort|den Wörtern|der Angabe|der Zahl) "
+ "^(Nach|Vor) (?:dem Wort|den (?:Wörtern|Worten)|der Angabe|der Zahl) "
+ Z
+ " (?:wird|werden) (?:"
+ WOERTER
@@ -675,7 +676,7 @@ final class BefehlErkenner {
// „wird/werden“ ergänzt {@link #vervollstaendigeVerbRahmenPunkt}.
private static final Pattern VERB_RAHMEN_PUNKT =
Pattern.compile(
- "^[Ii]n (.+?) (?=(?:die Wörter|das Wort|die Angabe|die Zahl) «)(.+?)[,.]?(?: und)?$");
+ "^[Ii]n (.+?) (?=(?:die (?:Wörter|Worte)|das Wort|die Angabe|die Zahl) «)(.+?)[,.]?(?: und)?$");
/** Das Verb eines Verb-Rahmens („Es werden ersetzt:“), sonst leer. */
static Optional<String> verbRahmen(String text) {
@@ -1640,8 +1641,8 @@ final class BefehlErkenner {
// des zuvor gesetzten Skopus (Gapping): „… und die Angabe „X“ wird gestrichen/eingefügt“.
private static final Pattern REINE_WORT_OPERATION =
Pattern.compile(
- "(?i)(?:die Angabe|nach der Angabe|vor der Angabe|die Wörter|die Worte|"
- + "nach den Wörtern|vor den Wörtern|das Wort)\\b");
+ "(?i)(?:die Angabe|nach der Angabe|vor der Angabe|die (?:Wörter|Worte)|die Worte|"
+ + "nach den (?:Wörtern|Worten)|vor den (?:Wörtern|Worten)|das Wort)\\b");
// Klausel, deren Subjekt ein Satzzeichen ist („das Komma wird durch … ersetzt“).
private static final Pattern SATZZEICHEN_SUBJEKT =
diff --git a/src/main/java/eu/mulk/aendggner/aenderung/parse/TextBereiniger.java b/src/main/java/eu/mulk/aendggner/aenderung/parse/TextBereiniger.java
index ffe3afa..c0a912f 100644
--- a/src/main/java/eu/mulk/aendggner/aenderung/parse/TextBereiniger.java
+++ b/src/main/java/eu/mulk/aendggner/aenderung/parse/TextBereiniger.java
@@ -295,6 +295,16 @@ public final class TextBereiniger {
+ "Nr\\.\\s*\\d+ vom \\d{1,2}\\. \\p{L}+ \\d{4}"
+ "(?:[ \\t\\n]*Seite \\d+ von \\d+)?[ \\t]*");
+ // GVBl. für Rheinland-Pfalz (elektronische Verkündung seit dem 1. Juli 2026): Der Seitenfuß
+ // („Gesetz- und Verordnungsblatt für das Land Rheinland-Pfalz - Nr. 21 vom 10. August 2026“)
+ // steht ebenso im Inhaltsstrom und zerschneidet dort das Zitat einer Neufassung („§ 18 erhält
+ // folgende Fassung:“ / Fußzeile / „„§ 18 …““). Die vorangehende Seitenzahl steht auf eigener
+ // Zeile und wird als Kolumnentitel erkannt.
+ private static final Pattern GVBL_RP_FUSS =
+ Pattern.compile(
+ "[ \\t]*Gesetz- und Verordnungsblatt für das Land Rheinland-Pfalz[ \\t\\n]*-[ \\t\\n]*"
+ + "Nr\\.\\s*\\d+ vom \\d{1,2}\\. \\p{L}+ \\d{4}[ \\t]*");
+
// Die Blattzählung des GBl. BW („Seite 2 von 7“) steht im Inhaltsstrom mitunter für sich allein,
// getrennt vom übrigen Seitenfuß, und zwar zwischen zwei Gliederungspunkten — sie hinge sonst dem
// vorangehenden Befehl an und machte ihn unkenntlich.
@@ -339,6 +349,7 @@ public final class TextBereiniger {
text = GVBL_TH_KOPF.matcher(text).replaceAll("\n");
text = GVBL_TH_FUSS.matcher(text).replaceAll("\n");
text = GBL_BW_FUSS.matcher(text).replaceAll("\n");
+ text = GVBL_RP_FUSS.matcher(text).replaceAll("\n");
var zeilen = entferneKolumnentitel(zerlegeInZeilen(text));
var verbunden = verbindeUmbrueche(zeilen);
// Falsch-positive markerlose Zusammenzüge („durch“ + „die“ → „durchdie“) reparieren — die