Die Java-API für reguläre Ausdrücke gibt an, dass \s
Leerzeichen übereinstimmen. Der Regex \\s\\s
sollte also mit zwei Leerzeichen übereinstimmen.
Pattern whitespace = Pattern.compile("\\s\\s");
matcher = whitespace.matcher(modLine);
while (matcher.find()) matcher.replaceAll(" ");
Ziel ist es, alle Instanzen von zwei aufeinanderfolgenden Leerzeichen durch ein einzelnes Leerzeichen zu ersetzen. Dies funktioniert jedoch nicht wirklich.
Habe ich ein schwerwiegendes Missverständnis von Regexen oder dem Begriff "Leerzeichen"?
"abc \xA0 def \x85 xyz"
zu teilen, um zu sehen, was ich meine: Dort gibt es nur drei Felder.Antworten:
Ja, Sie müssen das Ergebnis erfassen von
matcher.replaceAll()
:quelle
Sie können
\s
in Java keine Leerzeichen für den eigenen nativen Zeichensatz verwenden, da Java die Unicode-Leerraum-Eigenschaft nicht unterstützt - obwohl dies unbedingt erforderlich ist, um RL1.2 von UTS # 18 zu erfüllen! Was es hat, ist leider nicht standardkonform.Unicode definiert 26 Codepunkte als
\p{White_Space}
: 20 davon sind verschiedene Arten von\pZ
GeneralCategory = Separator , und die restlichen 6 sind\p{Cc}
GeneralCategory = Control .Weißraum ist eine ziemlich stabile Eigenschaft, und diese gibt es praktisch schon immer. Trotzdem hat Java keine Eigenschaft, die dem Unicode-Standard für diese entspricht. Sie müssen stattdessen Code wie den folgenden verwenden:
Jetzt können Sie
whitespace_charclass + "+"
als Muster in Ihrem verwendenreplaceAll
.Tut mir leid wegen all dem. Die regulären Ausdrücke von Java funktionieren mit ihrem eigenen nativen Zeichensatz einfach nicht sehr gut. Sie müssen also wirklich durch exotische Reifen springen, damit sie funktionieren.
Und wenn Sie denken , weißer Raum schlecht ist, sollten Sie sehen , was Sie tun müssen , um zu bekommen
\w
und\b
endlich richtig zu verhalten!Ja, es ist möglich und ja, es ist ein irrsinniges Durcheinander. Das ist sogar gemeinnützig. Der einfachste Weg, eine standardkonforme Regex-Bibliothek für Java zu erhalten, besteht darin, JNI auf die Intensivstation zu übertragen. Das macht Google für Android, weil OraSun's nicht mithalten kann.
Wenn Sie das nicht möchten, aber trotzdem bei Java bleiben möchten, habe ich eine von mir geschriebene Front-End-Regex-Umschreibungsbibliothek, die Javas Muster „korrigiert“, zumindest um sie an die Anforderungen von RL1.2a in UTS anzupassen # 18, Reguläre Unicode-Ausdrücke .
quelle
Für Java (nicht PHP, nicht Javascript, kein anderes):
quelle
Als ich eine Frage an ein Regexbuddy-Forum (Regex Developer Application) gesendet habe, habe ich eine genauere Antwort auf meine Java-Frage erhalten:
"Nachrichtenautor: Jan Goyvaerts
In Java enthalten die Kurzzeichen \ s, \ d und \ w nur ASCII-Zeichen. ... Dies ist kein Fehler in Java, sondern einfach eines der vielen Dinge, die Sie beachten müssen, wenn Sie mit regulären Ausdrücken arbeiten. Um alle Unicode-Leerzeichen sowie Zeilenumbrüche abzugleichen, können Sie [\ s \ p {Z}] in Java verwenden. RegexBuddy unterstützt noch keine Java-spezifischen Eigenschaften wie \ p {javaSpaceChar} (die genau den gleichen Zeichen wie [\ s \ p {Z}] entsprechen).
... \ s \ s stimmen mit zwei Leerzeichen überein, wenn die Eingabe nur ASCII ist. Das eigentliche Problem ist der OP-Code, wie aus der akzeptierten Antwort in dieser Frage hervorgeht. "
quelle
[\s\p{z}]
lässt das Unicode-Zeichen "nächste Zeile" U + 0085 weg. Verwenden Sie[\s\u0085\p{Z}]
.Scheint für mich zu arbeiten:
wird drucken:
Ich denke, Sie wollten dies anstelle Ihres Codes tun:
quelle
Für Ihren Zweck können Sie dieses Snnippet verwenden:
Dies normalisiert den Abstand auf einfach und entfernt auch die Start- und nachfolgenden Leerzeichen.
quelle
quelle
Java hat sich weiterentwickelt, seit dieses Problem zum ersten Mal angesprochen wurde. Mithilfe der
\p{Zs}
Gruppe können Sie alle Arten von Unicode-Leerzeichen abgleichen .Wenn Sie also einen oder mehrere exotische Räume durch einen einfachen Raum ersetzen möchten, können Sie dies tun:
Auch wissenswert, wenn Sie die verwendet haben
trim()
String - Funktion sollten Sie einen Blick auf die (relativ neu)strip()
,stripLeading()
undstripTrailing()
Funktionen auf Saiten. Das kann Ihnen helfen, alle Arten von Eichhörnchen-Leerzeichen abzuschneiden. Weitere Informationen dazu, welcher Speicherplatz enthalten ist, finden Sie in der Java-Character.isWhitespace()
Funktion.quelle
Die Verwendung von Leerzeichen in RE ist ein Schmerz, aber ich glaube, dass sie funktionieren. Das Problem des OP kann auch mit StringTokenizer oder der split () -Methode gelöst werden. Um jedoch RE zu verwenden (kommentieren Sie println () aus, um anzuzeigen, wie der Matcher den String aufteilt), finden Sie hier einen Beispielcode:
Es wird Folgendes erzeugt (mit javac kompilieren und an der Eingabeaufforderung ausführen):
% java Two21WS Initial: "ab cdef gh ij kl" Two21WS: "ab cdef gh ij kl"
quelle
replaceAll()
stattdessen einfach anrufen können ?