Manchmal möchte ich Leerzeichen abgleichen, aber keine Zeilenumbrüche.
Bislang habe ich mich auf [ \t]
. Gibt es einen weniger umständlichen Weg?
Manchmal möchte ich Leerzeichen abgleichen, aber keine Zeilenumbrüche.
Bislang habe ich mich auf [ \t]
. Gibt es einen weniger umständlichen Weg?
Verwenden Sie ein Doppelnegativ:
/[^\S\r\n]/
Das heißt, not-not-whitespace (das große S ergänzt sich) oder not-carriage-return oder not-newline. Die Verteilung des äußeren not ( d.h. die ergänzende ^
in der Zeichenklasse) mit De-Morgansches Gesetz ist dies gleichbedeutend mit "Leerzeichen, aber kein Wagenrücklauf oder Zeilenumbruch". Einschließlich beider \r
et \n
im Muster behandelt alle Unix- (LF), klassischen Mac OS- (CR) und DOS-artigen (CR LF) Zeilenumbruch-Konventionen .
Sie brauchen mich nicht beim Wort zu nehmen:
#! /usr/bin/env perl
use strict;
use warnings;
use 5.005; # for qr//
my $ws_not_crlf = qr/[^\S\r\n]/;
for (' ', '\f', '\t', '\r', '\n') {
my $qq = qq["$_"];
printf "%-4s => %s\n", $qq,
(eval $qq) =~ $ws_not_crlf ? "match" : "no match";
}
Sortie :
" " => match
"\\f" => match
"\\t" => match
"\\r" => no match
"\\n" => no match
Beachten Sie den Ausschluss des vertikalen Tabulators, aber das ist behandelt in Version 5.18 .
Bevor Sie zu sehr protestieren: Die Perl-Dokumentation verwendet die gleiche Technik. Eine Fußnote in der "Whitespace"-Abschnitt von perlrecharclass liest
Vor Perl v5.18,
\s
nicht mit dem vertikalen Reiter übereinstimmte.[^\S\cK]
(undeutlich) mit dem übereinstimmt, was\s
traditionell getan.
Le derselbe Abschnitt von perlrecharclass schlägt auch andere Ansätze vor, die den Widerstand der Sprachlehrer gegen das doppelte Negativ nicht verletzen werden.
Außerhalb der Gebietsschema- und Unicode-Regeln oder wenn die /a
Schalter in Kraft ist, " \s
passt zu [\t\n\f\r ]
und, ab Perl v5.18, der vertikale Tabulator, \cK
." Ablegen \r
et \n
zu verlassen /[\t\f\cK ]/
für passende Leerzeichen, aber nicht für Zeilenumbrüche.
Wenn es sich bei Ihrem Text um Unicode handelt, verwenden Sie einen Code ähnlich dem unten stehenden, um ein Muster aus der Tabelle in den oben erwähnten Abschnitt über die Dokumentation .
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
EOTable
my $class;
while (/^0x([0-9a-f]{4})\s+([A-Z\s]+)/mg) {
my($hex,$name) = ($1,$2);
next if $name =~ /\b(?:CR|NL|NEL|SEPARATOR)\b/;
$class .= "\\N{U+$hex}";
}
qr/[$class]/u;
}
Der Trick mit dem Doppelnegativ ist auch für die Zuordnung von Buchstaben nützlich. Denken Sie daran, dass \w
entspricht "Wortzeichen", alphabetischen Zeichen et Ziffern und Unterstrich. Wir hässlichen Amerikaner wollen es manchmal als, sagen wir, schreiben,
if (/[A-Za-z]+/) { ... }
aber eine doppelt-negative Zeichenklasse kann das Gebietsschema respektieren:
if (/[^\W\d_]+/) { ... }
Die Formulierung "ein Wortzeichen, aber keine Ziffer oder ein Unterstrich" ist ein wenig undurchsichtig. Eine POSIX-Zeichenklasse kommuniziert die Absicht direkter
if (/[[:alpha:]]+/) { ... }
oder mit einer Unicode-Eigenschaft wie szbalint vorgeschlagen
if (/\p{Letter}+/) { ... }
Die Perl-Versionen 5.10 und später unterstützen zusätzliche vertikale und horizontale Zeichenklassen, \v
et \h
sowie die allgemeine Leerzeichenklasse \s
Die sauberste Lösung ist die Verwendung des horizontales Leerzeichen Charakterklasse \h
. Dies entspricht den Tabulatoren und Leerzeichen des ASCII-Satzes, den nicht umbrechenden Leerzeichen des erweiterten ASCII-Satzes oder einem der folgenden 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
Le Vertikaler Raum Muster \v
ist weniger nützlich, passt aber zu diesen Zeichen
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 Whitespace-Zeichen, die mit \v
und achtzehn horizontale, die mit \h
. \s
entspricht dreiundzwanzig Zeichen
Alle Whitespace-Zeichen sind entweder vertikal ou horizontal ohne Überschneidungen, aber sie sind keine richtigen Teilmengen, weil \h
entspricht auch U+00A0 NO-BREAK SPACE, und \v
passt auch auf U+0085 NEXT LINE, was beides nicht der Fall ist. \s
Eine Variante von Gregs Antwort die auch Zeilenumbrüche enthält:
/[^\S\r\n]/
Diese Regex ist sicherer als /[^\S\n]/
ohne \r
. Meine Überlegung ist, dass Windows die \r\n
für Zeilenumbrüche, und Mac OS 9 verwendete \r
. Es ist unwahrscheinlich, dass Sie \r
ohne \n
Aber wenn Sie es finden, kann es nichts anderes bedeuten als einen Zeilenumbruch. Da also \r
einen Zeilenumbruch bedeuten kann, sollten wir auch diesen ausschließen.
Die unten stehende Regex würde auf Leerzeichen passen, aber nicht auf einen Zeilenumbruch.
(?:(?!\n)\s)
Wenn Sie auch einen Wagenrücklauf hinzufügen möchten, fügen Sie \r
mit dem |
Operator innerhalb der negativen Vorausschau.
(?:(?![\n\r])\s)
hinzufügen +
nach der nicht erfassenden Gruppe, um einem oder mehreren Leerzeichen zu entsprechen.
(?:(?![\n\r])\s)+
Ich weiß nicht, warum ihr die POSIX-Zeichenklasse nicht erwähnt habt [[:blank:]]
die auf alle horizontalen Leerzeichen ( Leerzeichen und Tabulatoren ). Diese POSIX-Chrakterklasse würde auf BRE( Grundlegende REgularausdrücke ), ERE( Erweiterte reguläre Ausdrücke ), PCRE( Perl-kompatible reguläre Ausdrücke ).
CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.