Übrigens sind diese Zeichen auch "Leerzeichen" : [\r\f].
Eugene Yarmash
2
@ Eugeney macht noch jemand Formular-Feeds? (\ f's)
Aran Mulholland
1
@AranMulholland: Jeder, der einen zeichenorientierten Drucker hat. Die meisten Drucker haben einen Zeichenmodus sowie PostScript oder wie auch immer die Hewlett Packard-Oberfläche heißt. Um eine Seite zu werfen, senden Sie einen Formular-Feed.
Borodin
1
@Borodin Hewlett Packard's heißt PCL (Printer Control Language).
CB_Ron
Antworten:
182
Perl - Versionen 5.10 und höher unterstützen Tochter vertikale und horizontale Zeichenklassen, \vund \hsowie die allgemeine Leerzeichenklasse\s
Die sauberste Lösung besteht darin, die horizontale Leerzeichenzeichenklasse zu verwenden \h. Dies entspricht der Registerkarte und dem Leerzeichen aus dem ASCII-Satz, dem nicht unterbrechenden Leerzeichen aus dem erweiterten ASCII-Satz oder einem dieser Unicode-Zeichen
U+0009 CHARACTER TABULATION
U+0020 SPACE
U+00A0 NO-BREAK SPACE (not matched by \s)
U+1680 OGHAM SPACE MARK
U+2000 EN QUAD
U+2001 EM QUAD
U+2002 EN SPACE
U+2003 EM SPACE
U+2004 THREE-PER-EM SPACE
U+2005 FOUR-PER-EM SPACE
U+2006 SIX-PER-EM SPACE
U+2007 FIGURE SPACE
U+2008 PUNCTUATION SPACE
U+2009 THIN SPACE
U+200A HAIR SPACE
U+202F NARROW NO-BREAK SPACE
U+205F MEDIUM MATHEMATICAL SPACE
U+3000 IDEOGRAPHIC SPACE
Das vertikale Raummuster \vist weniger nützlich, stimmt jedoch mit diesen Zeichen überein
U+000A LINE FEED
U+000B LINE TABULATION
U+000C FORM FEED
U+000D CARRIAGE RETURN
U+0085 NEXT LINE (not matched by \s)
U+2028 LINE SEPARATOR
U+2029 PARAGRAPH SEPARATOR
Es gibt sieben vertikale Leerzeichen, die übereinstimmen, \vund achtzehn horizontale Leerzeichen , die übereinstimmen \h. \sentspricht dreiundzwanzig Zeichen
Alle Leerzeichen sind entweder vertikal oder horizontal ohne Überlappung, aber sie sind keine richtigen Teilmengen, da sie \hauch mit U + 00A0 NO-BREAK SPACE und \vU + 0085 NEXT LINE übereinstimmen, von denen keine übereinstimmen\s
\hfunktioniert nur in den unterstützten Sprachen PCRE.
Avinash Raj
14
@AvinashRaj: Diese Frage bezieht sich auf Perl, das PCRE
Borodin
2
@ AvashashRaj: Außer das [[:blank:]]passt nicht No-Break Space - oder"\xA0"
Borodin
6
\hIch möchte erwähnen, dass dies perfekt für meinen Anwendungsfall funktioniert hat, bei dem in Notepad ++ ein oder mehrere zusammenhängende Leerzeichen ohne neue Zeilen gefunden / ersetzt wurden. Sonst (einfach) hat nichts funktioniert.
Squidbe
8
Was Perl \hetwas unüblich macht, ist seine Einbeziehung von MONGOLIAN VOWEL SEPARATOR. Unicode betrachtet es nicht als Leerzeichen. Aus diesem Grund unterscheidet sich Perl \hvon POSIX blank( [[:blank:]]in Perl, \p{Blank}in Java) und Java 8 \h. Zugegeben, es ist ein Randfall.
Aleksandr Dubinsky
360
Verwenden Sie ein doppeltes Negativ:
/[^\S\r\n]/
Das heißt, kein Nicht-Leerzeichen (das Kapital S ergänzt) oder kein Wagenrücklauf oder kein Zeilenumbruch. Wenn Sie das äußere Nicht ( dh die Ergänzung ^in der Zeichenklasse) mit De Morgans Gesetz verteilen, entspricht dies „Leerzeichen, aber nicht Wagenrücklauf oder Zeilenumbruch“. Wenn Sie beide \rund \ndas Muster korrekt einschließen , werden alle Unline- (LF), klassischen Mac OS- (CR) und DOS- ish- (CR LF) Newline-Konventionen korrekt behandelt .
Außerhalb der Gebietsschema- und Unicode-Regeln oder wenn der /aSchalter aktiv ist, " \sstimmt überein [\t\n\f\r ]und ab Perl v5.18 mit der vertikalen Registerkarte \cK". Verwerfen \rund \nverlassen, /[\t\f\cK ]/um passende Leerzeichen, aber keine Zeilenumbrüche zu erhalten.
sub ws_not_nl {local($_)=<<'EOTable';0x0009 CHARACTER TABULATION h s
0x000a LINE FEED (LF) vs
0x000b LINE TABULATION vs [1]0x000c FORM FEED (FF) vs
0x000d CARRIAGE RETURN (CR) vs
0x0020 SPACE h s
0x0085 NEXT LINE (NEL) vs [2]0x00a0 NO-BREAK SPACE h s [2]0x1680 OGHAM SPACE MARK h s
0x2000 EN QUAD h s
0x2001 EM QUAD h s
0x2002 EN SPACE h s
0x2003 EM SPACE h s
0x2004 THREE-PER-EM SPACE h s
0x2005 FOUR-PER-EM SPACE h s
0x2006 SIX-PER-EM SPACE h s
0x2007 FIGURE SPACE h s
0x2008 PUNCTUATION SPACE h s
0x2009 THIN SPACE h s
0x200a HAIR SPACE h s
0x2028 LINE SEPARATOR vs
0x2029 PARAGRAPH SEPARATOR vs
0x202f NARROW NO-BREAK SPACE h s
0x205f MEDIUM MATHEMATICAL SPACE h s
0x3000 IDEOGRAPHIC SPACE h s
EOTablemy $class;while(/^0x([0-9a-f]{4})\s+([A-Z\s]+)/mg){my($hex,$name)=($1,$2);nextif $name =~/\b(?:CR|NL|NEL|SEPARATOR)\b/;
$class .="\\N{U+$hex}";}
qr/[$class]/u;}
Andere Anwendungen
Der doppelt negative Trick ist auch praktisch, um alphabetische Zeichen abzugleichen. Denken Sie daran, dass dies \wmit „Wortzeichen“, alphabetischen Zeichen sowie Ziffern und Unterstrichen übereinstimmt . Wir hässlichen Amerikaner wollen es manchmal so schreiben, als ob
if(/[A-Za-z]+/){...}
Eine doppelt negative Zeichenklasse kann jedoch das Gebietsschema respektieren:
if(/[^\W\d_]+/){...}
Auf diese Weise „ein Wortzeichen, aber keine Ziffer oder Unterstrich“ auszudrücken, ist etwas undurchsichtig. Eine POSIX-Zeichenklasse kommuniziert die Absicht direkter
if(/[[:alpha:]]+/){...}
oder mit einer Unicode-Eigenschaft, wie von szbalint vorgeschlagen
Clever, aber das Verhalten ist sehr überraschend, und ich sehe nicht, wie es weniger umständlich ist.
Qwertie
7
@ Qwertie: Was ist überraschend? Weniger umständlich als was?
Ysth
9
Hervorragend schrecklich.
9
Das ist sehr gut. Wie gewünscht stimmen Sie mit Leerzeichen überein (nicht nur mit einigen Leerzeichen), und Sie schließen das Zeilenvorschubzeichen aus. Ihre Lösung befasst sich nicht mit der Frage: "Welche Leerzeichen gibt es?", Wie es nicht sein sollte. Genau das habe ich gesucht. (Wie @Rory erwähnte, ein ‚Newline‘ kann auch \r, zB unter Windows, so denken Sie daran auch diejenigen , die aus dem Spiel gewählte Art: /[^\S\r\n]/)
Timo
1
Dies wird sicherlich den Bedürfnissen des OP und praktisch aller anderen, die diese Frage suchen, gerecht (jedenfalls englischsprachig). Aber es ist immer noch eine schlechte Antwort. Es gibt einfach keine Entschuldigung für die Verwendung dieser Lösung, wenn sie \hverfügbar ist.
Alan Moore
49
Eine Variation von Gregs Antwort , die auch Wagenrückläufe enthält:
/[^\S\r\n]/
Diese Regex ist sicherer als /[^\S\n]/mit Nr \r. Meine Argumentation ist, dass Windows \r\nfür Zeilenumbrüche und Mac OS 9 verwendet \r. Sie sind wahrscheinlich nicht finden , \rohne \nheute, aber wenn Sie es finden, es könnte nicht gemein alles andere als eine neue Zeile. Da \rdies eine neue Zeile bedeuten kann, sollten wir sie auch ausschließen.
+1 Gregs Lösung hat meinen Text beschädigt, deine hat gut funktioniert.
Timo Huovinen
Sie werden überrascht sein, wie viele Programme noch "\ r" für Zeilenenden verwenden. Manchmal habe ich eine Weile gebraucht, um herauszufinden, dass mein Problem darin bestand, dass die Datei diese verwendete. Oder dass es die MacRoman-Zeichenkodierung verwendet hat ...
mivk
2
sieht so aus, als hätte @Greg es zuerst "falsch" geändert und dich nicht gutgeschrieben. Deshalb stimme ich hier ab.
Andre Elrico
14
Der unten stehende reguläre Ausdruck würde mit Leerzeichen übereinstimmen, jedoch nicht mit einem neuen Linienzeichen.
Ich weiß nicht, warum Sie die POSIX-Zeichenklasse, [[:blank:]]die mit horizontalen Leerzeichen ( Leerzeichen und Tabulatoren ) übereinstimmt, nicht erwähnt haben . Diese POSIX-Chracter-Klasse funktioniert mit BRE ( Basic REgular Expressions ), ERE ( Extended Regular Expression ) und PCRE ( Perl Compatible Regular Expression ).
Was Sie suchen, ist die POSIX- blankZeichenklasse. In Perl wird darauf verwiesen als:
[[:blank:]]
in Java (nicht vergessen zu aktivieren UNICODE_CHARACTER_CLASS):
\p{Blank}
Im Vergleich zu ähnlichen \hwird POSIX blankvon einigen weiteren Regex-Engines unterstützt ( Referenz ). Ein Hauptvorteil besteht darin, dass seine Definition in Anhang C festgelegt ist: Kompatibilitätseigenschaften von regulären Unicode-Ausdrücken und Standard für alle Regex-Varianten, die Unicode unterstützen. (In Perl wird beispielsweise \hzusätzlich das eingeschlossen MONGOLIAN VOWEL SEPARATOR.) Ein Argument dafür \hist jedoch, dass immer Unicode-Zeichen erkannt werden (auch wenn sich die Engines nicht darüber einig sind), während POSIX-Zeichenklassen häufig standardmäßig ASCII sind -nur (wie in Java).
Das Problem ist jedoch, dass selbst das Festhalten an Unicode das Problem nicht zu 100% löst. Berücksichtigen Sie die folgenden Zeichen, die in Unicode nicht als Leerzeichen gelten:
Der oben erwähnte mongolische Vokaltrenner ist aus wahrscheinlich guten Gründen nicht enthalten. Es kommt zusammen mit 200C und 200D in Wörtern (AFAIK) vor und verstößt daher gegen die Grundregel, die alle anderen Leerzeichen befolgen: Sie können damit tokenisieren. Sie sind eher Modifikatoren. Allerdings ZERO WIDTH SPACE, WORD JOINERund ZERO WIDTH NON-BREAKING SPACE(wenn es als etwas anderes als eine Byte-Reihenfolge - Marke verwendet wird ) paßt die Leerzeichen Regel in meinem Buch. Daher füge ich sie in meine horizontale Leerzeichen-Zeichenklasse ein.
In Java:
static public final String HORIZONTAL_WHITESPACE ="[\\p{Blank}\\u200B\\u2060\\uFFEF]"
Sie müssen der Java-Kompilierung die entsprechenden Regexp-Kompilierungsflags hinzufügen und Java 7 oder höher ausführen. Auf jeden Fall ging es bei der Frage überhaupt nicht um Java oder PCRE, daher ist dies alles unerheblich.
Tchrist
@tchrist Vielen Dank für den Hinweis. Ich werde meine Antwort aktualisieren. Ich bin jedoch nicht der Meinung, dass meine Antwort irrelevant ist. Was unerheblich ist, ist das perlTag in der ursprünglichen Frage.
Aleksandr Dubinsky
1
@AleksandrDubinsky, \ p {Blank} wird in JavaScript nicht unterstützt, also definitiv nicht "Standard für alle Regex-Aromen" -1
Valentin Vasilyev
Am informativsten. Ich finde es beunruhigend zu wissen, dass es keine allgemeine und vollständige "horizontale Leerzeichen" -Kurzzeichenklasse gibt und dass solche Horrorarten [\p{Blank}\u200b\u180e]erforderlich sind. Zugegeben, es ist sinnvoll, dass ein Vokaltrennzeichen nicht als Leerzeichen betrachtet wird, aber warum Leerzeichen mit der Breite Null nicht in Klassen wie \sund enthalten sind \p{Blank}, schlägt mich.
Timo
Follow-up: Ich habe gelesen, dass beide als "grenzenneutral" gelten, obwohl das nicht erklärt, warum .
Timo
-4
m/ /gGeben Sie einfach Platz / /, und es wird funktionieren. Oder verwenden Sie \S- es ersetzt alle Sonderzeichen wie Tabulatoren, Zeilenumbrüche, Leerzeichen usw.
[\r\f]
.Antworten:
Perl - Versionen 5.10 und höher unterstützen Tochter vertikale und horizontale Zeichenklassen,
\v
und\h
sowie die allgemeine Leerzeichenklasse\s
Die sauberste Lösung besteht darin, die horizontale Leerzeichenzeichenklasse zu verwenden
\h
. Dies entspricht der Registerkarte und dem Leerzeichen aus dem ASCII-Satz, dem nicht unterbrechenden Leerzeichen aus dem erweiterten ASCII-Satz oder einem dieser Unicode-ZeichenDas vertikale Raummuster
\v
ist weniger nützlich, stimmt jedoch mit diesen Zeichen übereinEs gibt sieben vertikale Leerzeichen, die übereinstimmen,
\v
und achtzehn horizontale Leerzeichen , die übereinstimmen\h
.\s
entspricht dreiundzwanzig ZeichenAlle Leerzeichen sind entweder vertikal oder horizontal ohne Überlappung, aber sie sind keine richtigen Teilmengen, da sie
\h
auch mit U + 00A0 NO-BREAK SPACE und\v
U + 0085 NEXT LINE übereinstimmen, von denen keine übereinstimmen\s
quelle
\h
funktioniert nur in den unterstützten SprachenPCRE
.[[:blank:]]
passt nicht No-Break Space -
oder"\xA0"
\h
Ich möchte erwähnen, dass dies perfekt für meinen Anwendungsfall funktioniert hat, bei dem in Notepad ++ ein oder mehrere zusammenhängende Leerzeichen ohne neue Zeilen gefunden / ersetzt wurden. Sonst (einfach) hat nichts funktioniert.\h
etwas unüblich macht, ist seine Einbeziehung vonMONGOLIAN VOWEL SEPARATOR
. Unicode betrachtet es nicht als Leerzeichen. Aus diesem Grund unterscheidet sich Perl\h
von POSIXblank
([[:blank:]]
in Perl,\p{Blank}
in Java) und Java 8\h
. Zugegeben, es ist ein Randfall.Verwenden Sie ein doppeltes Negativ:
Das heißt, kein Nicht-Leerzeichen (das Kapital S ergänzt) oder kein Wagenrücklauf oder kein Zeilenumbruch. Wenn Sie das äußere Nicht ( dh die Ergänzung
^
in der Zeichenklasse) mit De Morgans Gesetz verteilen, entspricht dies „Leerzeichen, aber nicht Wagenrücklauf oder Zeilenumbruch“. Wenn Sie beide\r
und\n
das Muster korrekt einschließen , werden alle Unline- (LF), klassischen Mac OS- (CR) und DOS- ish- (CR LF) Newline-Konventionen korrekt behandelt .Ich brauche nicht mein Wort dafür zu nehmen:
Ausgabe:
Beachten Sie den Ausschluss der vertikalen Registerkarte, dies wird jedoch in Version 5.18 behandelt .
Bevor zu heftige Einwände erhoben werden, wird in der Perl-Dokumentation dieselbe Technik verwendet. Eine Fußnote im Abschnitt "Leerzeichen" der Perlrecharklasse lautet
Der gleiche Abschnitt der Perlrecharklasse schlägt auch andere Ansätze vor, die den Widerstand der Sprachlehrer gegen Doppel-Negative nicht verletzen .
Außerhalb der Gebietsschema- und Unicode-Regeln oder wenn der
/a
Schalter aktiv ist, "\s
stimmt überein[\t\n\f\r ]
und ab Perl v5.18 mit der vertikalen Registerkarte\cK
". Verwerfen\r
und\n
verlassen,/[\t\f\cK ]/
um passende Leerzeichen, aber keine Zeilenumbrüche zu erhalten.Wenn Ihr Text Unicode ist, verwenden Sie Code ähnlich dem folgenden Unter, um ein Muster aus der Tabelle im oben genannten Dokumentationsabschnitt zu erstellen .
Andere Anwendungen
Der doppelt negative Trick ist auch praktisch, um alphabetische Zeichen abzugleichen. Denken Sie daran, dass dies
\w
mit „Wortzeichen“, alphabetischen Zeichen sowie Ziffern und Unterstrichen übereinstimmt . Wir hässlichen Amerikaner wollen es manchmal so schreiben, als obEine doppelt negative Zeichenklasse kann jedoch das Gebietsschema respektieren:
Auf diese Weise „ein Wortzeichen, aber keine Ziffer oder Unterstrich“ auszudrücken, ist etwas undurchsichtig. Eine POSIX-Zeichenklasse kommuniziert die Absicht direkter
oder mit einer Unicode-Eigenschaft, wie von szbalint vorgeschlagen
quelle
\r
, zB unter Windows, so denken Sie daran auch diejenigen , die aus dem Spiel gewählte Art:/[^\S\r\n]/
)\h
verfügbar ist.Eine Variation von Gregs Antwort , die auch Wagenrückläufe enthält:
Diese Regex ist sicherer als
/[^\S\n]/
mit Nr\r
. Meine Argumentation ist, dass Windows\r\n
für Zeilenumbrüche und Mac OS 9 verwendet\r
. Sie sind wahrscheinlich nicht finden ,\r
ohne\n
heute, aber wenn Sie es finden, es könnte nicht gemein alles andere als eine neue Zeile. Da\r
dies eine neue Zeile bedeuten kann, sollten wir sie auch ausschließen.quelle
Der unten stehende reguläre Ausdruck würde mit Leerzeichen übereinstimmen, jedoch nicht mit einem neuen Linienzeichen.
DEMO
Wenn Sie auch Wagenrücklauf hinzufügen möchten, fügen Sie
\r
mit dem|
Operator innerhalb des negativen Lookaheads hinzu.DEMO
Fügen Sie
+
nach der Nicht-Erfassungsgruppe eines oder mehr Leerräume passen.DEMO
Ich weiß nicht, warum Sie die POSIX-Zeichenklasse,
[[:blank:]]
die mit horizontalen Leerzeichen ( Leerzeichen und Tabulatoren ) übereinstimmt, nicht erwähnt haben . Diese POSIX-Chracter-Klasse funktioniert mit BRE ( Basic REgular Expressions ), ERE ( Extended Regular Expression ) und PCRE ( Perl Compatible Regular Expression ).DEMO
quelle
Was Sie suchen, ist die POSIX-
blank
Zeichenklasse. In Perl wird darauf verwiesen als:in Java (nicht vergessen zu aktivieren
UNICODE_CHARACTER_CLASS
):Im Vergleich zu ähnlichen
\h
wird POSIXblank
von einigen weiteren Regex-Engines unterstützt ( Referenz ). Ein Hauptvorteil besteht darin, dass seine Definition in Anhang C festgelegt ist: Kompatibilitätseigenschaften von regulären Unicode-Ausdrücken und Standard für alle Regex-Varianten, die Unicode unterstützen. (In Perl wird beispielsweise\h
zusätzlich das eingeschlossenMONGOLIAN VOWEL SEPARATOR
.) Ein Argument dafür\h
ist jedoch, dass immer Unicode-Zeichen erkannt werden (auch wenn sich die Engines nicht darüber einig sind), während POSIX-Zeichenklassen häufig standardmäßig ASCII sind -nur (wie in Java).Das Problem ist jedoch, dass selbst das Festhalten an Unicode das Problem nicht zu 100% löst. Berücksichtigen Sie die folgenden Zeichen, die in Unicode nicht als Leerzeichen gelten:
U + FEFF NULL BREITE NICHT BRECHENDER RAUM
Entnommen aus https://en.wikipedia.org/wiki/White-space_character
Der oben erwähnte mongolische Vokaltrenner ist aus wahrscheinlich guten Gründen nicht enthalten. Es kommt zusammen mit 200C und 200D in Wörtern (AFAIK) vor und verstößt daher gegen die Grundregel, die alle anderen Leerzeichen befolgen: Sie können damit tokenisieren. Sie sind eher Modifikatoren. Allerdings
ZERO WIDTH SPACE
,WORD JOINER
undZERO WIDTH NON-BREAKING SPACE
(wenn es als etwas anderes als eine Byte-Reihenfolge - Marke verwendet wird ) paßt die Leerzeichen Regel in meinem Buch. Daher füge ich sie in meine horizontale Leerzeichen-Zeichenklasse ein.In Java:
quelle
perl
Tag in der ursprünglichen Frage.[\p{Blank}\u200b\u180e]
erforderlich sind. Zugegeben, es ist sinnvoll, dass ein Vokaltrennzeichen nicht als Leerzeichen betrachtet wird, aber warum Leerzeichen mit der Breite Null nicht in Klassen wie\s
und enthalten sind\p{Blank}
, schlägt mich.m/ /g
Geben Sie einfach Platz/ /
, und es wird funktionieren. Oder verwenden Sie\S
- es ersetzt alle Sonderzeichen wie Tabulatoren, Zeilenumbrüche, Leerzeichen usw.quelle