aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/eu
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/eu')
-rw-r--r--src/main/java/eu/mulk/aendggner/aenderung/parse/StellenParser.java19
-rw-r--r--src/main/java/eu/mulk/aendggner/aenderung/parse/TextBereiniger.java13
2 files changed, 31 insertions, 1 deletions
diff --git a/src/main/java/eu/mulk/aendggner/aenderung/parse/StellenParser.java b/src/main/java/eu/mulk/aendggner/aenderung/parse/StellenParser.java
index 473eb14..786c812 100644
--- a/src/main/java/eu/mulk/aendggner/aenderung/parse/StellenParser.java
+++ b/src/main/java/eu/mulk/aendggner/aenderung/parse/StellenParser.java
@@ -133,7 +133,7 @@ public final class StellenParser {
i++;
}
case "Teil", "Teils", "Buch", "Buches", "Kapitel", "Kapitels", "Abschnitt", "Abschnitts",
- "Unterabschnitt", "Unterabschnitts", "Anlage", "Anlagen" -> {
+ "Unterabschnitt", "Unterabschnitts" -> {
var wert = naechstesWort(woerter, i);
if (wert == null || !NUMMER_WERT.matcher(wert).matches()) {
return Optional.empty();
@@ -141,6 +141,23 @@ public final class StellenParser {
komponenten.add(new Stelle.Gliederungseinheit(gliederungsArt(wort), wert));
i++;
}
+ case "Anlage", "Anlagen" -> {
+ var wert = naechstesWort(woerter, i);
+ if (wert != null && NUMMER_WERT.matcher(wert).matches()) {
+ komponenten.add(new Stelle.Gliederungseinheit("Anlage", wert));
+ i++;
+ continue;
+ }
+ // „die Anlage zu § 2 Absatz 4 Satz 1“ — ein Gesetz mit einer einzigen Anlage benennt sie
+ // nach der Vorschrift, zu der sie gehört. Wie beim „Anhang“ trägt sie dann die enbez
+ // „Anlage“; der Zusatz identifiziert sie nur und ist nicht selbst Änderungsziel. Er
+ // reicht bis zum Ende der Stellenangabe und wird deshalb übersprungen — sonst läse der
+ // Parser das darin genannte „§ 2“ als Ziel und änderte die falsche Norm.
+ komponenten.add(new Stelle.Gliederungseinheit("Anlage", ""));
+ if ("zu".equals(wert)) {
+ i = woerter.length;
+ }
+ }
case "Anhang" -> komponenten.add(new Stelle.Gliederungseinheit("Anhang", ""));
case "Inhaltsübersicht" -> komponenten.add(new Stelle.Inhaltsuebersicht());
case "Überschrift" -> komponenten.add(new Stelle.Ueberschrift());
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 d0e37f8..fc54554 100644
--- a/src/main/java/eu/mulk/aendggner/aenderung/parse/TextBereiniger.java
+++ b/src/main/java/eu/mulk/aendggner/aenderung/parse/TextBereiniger.java
@@ -206,12 +206,19 @@ public final class TextBereiniger {
private static final Pattern SACHNUMMER_MIT_LEERZEICHEN =
Pattern.compile("(§|Art\\.) (\\d+) ([a-z])(?![a-zäöüß).])");
+ /** C0-Steuerzeichen außer Tabulator und Zeilenumbruch; im Fließtext stets Extraktionsmüll. */
+ private static final Pattern STEUERZEICHEN = Pattern.compile("[\\x00-\\x08\\x0B\\x0C\\x0E-\\x1F]");
+
private TextBereiniger() {}
public static String bereinige(String rohText) {
// Geschützte Leerzeichen (GVBl-Satz: „§  1“, „Abs.  2“) sind für Javas \s und
// String.strip unsichtbar — früh auf gewöhnliche Leerzeichen normalisieren.
var text = rohText.replace(' ', ' ').replace(' ', ' ');
+ // Steuerzeichen aus fehlgeleiteten Glyphenzuordnungen (im GVBl. für Berlin trägt der Einzug
+ // der Aufzählungsglieder ein U+0007). Sie sind unsichtbar, stehen aber vor dem Befehlstext und
+ // ließen dessen Zeilenanfangs-Anker ins Leere greifen.
+ text = STEUERZEICHEN.matcher(text).replaceAll("");
text = normalisiereAnfuehrungszeichen(text);
text = INVERTIERTES_ZITAT.matcher(text).replaceAll("$1„($2) ");
text = INVERTIERTES_PARAGRAPH_ZITAT.matcher(text).replaceAll("$1„$2");
@@ -290,6 +297,12 @@ public final class TextBereiniger {
.replace("undwird ", "und wird ")
.replace("Kommaeingefügt", "Komma eingefügt")
.replace("Kommaersetzt", "Komma ersetzt")
+ // Umgekehrter Satzfehler: ein Leerzeichen mitten in der Befehlsvokabel („ein ge-“ +
+ // „fügt“ → „ein gefügt“, GVBl. Berlin 2026/17). Nur Fügungen, die als Wortfolge im
+ // Deutschen nicht vorkommen — „er setzt“ etwa bliebe unangetastet.
+ .replace("ein gefügt", "eingefügt")
+ .replace("an gefügt", "angefügt")
+ .replace("auf gehoben", "aufgehoben")
// Kontextrahmen, an den der folgende Unterpunkt geklebt wurde („geändertaa) In …“).
.replaceAll("(wie folgt geändert:?)(?=[a-z]{1,3}\\)|\\d+[a-z]?\\.)", "$1\n");
}