@eugeney czy ktoś nadal robi przesyłanie formularzy? (\ f's)
Aran Mulholland
1
@AranMulholland: Każdy, kto ma drukarkę zorientowaną na znaki. Większość drukarek ma tryb znakowy, a także PostScript lub jakikolwiek inny interfejs Hewlett Packard, i aby rzucić stronę, wysyłasz formularz.
Borodin
1
@Borodin Hewlett Packard's nazywa się PCL (Printer Control Language).
CB_Ron
Odpowiedzi:
182
Perl wersje 5.10 i później zależne wsparcie klas postaci pionowej i poziomej, \va \h, jak również ogólny spacje klasa znaków\s
Najczystszym rozwiązaniem jest użycie poziomej klasy znaków białych znaków \h. Spowoduje to dopasowanie tabulacji i spacji z zestawu ASCII, nierozdzielania spacji z rozszerzonego ASCII lub dowolnego z tych znaków Unicode
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
Pionowa przestrzeń wzór \vjest mniej przydatna, ale pasuje do tych znaków
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
Istnieje siedem pasujących znaków pionowych białych znaków \vi osiemnaście pasujących znaków poziomych \h. \sdopasowuje dwadzieścia trzy znaki
Wszystkie znaki białych znaków są pionowe lub poziome, bez nakładania się, ale nie są odpowiednimi podzestawami, ponieważ \hrównież pasują do U + 00A0 BEZ PRZERWU, a \vtakże pasują do U + 0085 NASTĘPNA LINIA, z których żaden nie jest dopasowany\s
@AvinashRaj: To pytanie dotyczy Perla, który z pewnością obsługuje PCRE
Borodin
2
@AvinashRaj: Tyle że [[:blank:]]nie pasuje do spacji bez przerwy - lub"\xA0"
Borodin
6
Chcę wspomnieć, że \hdziałało idealnie w moim przypadku użycia, który szukał / zamienił w Notepad ++ na co najmniej 1 ciągłym spacji nie nowej linii. Nic innego (proste) nie działało.
squidbe
8
To, co sprawia, że Perl jest \hnieco niestandardowy, to jego włączenie MONGOLIAN VOWEL SEPARATOR. Unicode nie uważa tego za spację. Z tego powodu Perl \hróżni się od POSIX blank( [[:blank:]]w Perlu, \p{Blank}w Javie) i Java 8 \h. Trzeba przyznać, że to przypadek na krawędzi.
Aleksandr Dubinsky,
362
Użyj podwójnie ujemnego:
/[^\S\r\n]/
Oznacza to, że nie-spacja (duża litera S uzupełnia) lub zwrot-przewóz lub brak nowej linii. Dystrybucja zewnętrzna nie ( tj . Uzupełniająca^ w klasie postaci) z prawem De Morgana , jest to równoważne z „białymi spacjami, ale nie znakiem powrotu karetki lub znakiem nowej linii”. Włączenie zarówno wzorca, jak \ri \nwzorca poprawnie obsługuje wszystkie konwencje nowego wiersza Uniksa (LF), klasycznego Mac OS (CR) i DOS-ish (CR LF) .
Przed zbyt surowym sprzeciwem dokumentacja Perla używa tej samej techniki. Przypis w sekcji „Białe znaki” w perlrecharclass brzmi:
W wersjach wcześniejszych niż Perl v5.18 \snie pasował do zakładki pionowej. [^\S\cK](niejasno) pasuje do tego, co \stradycyjnie robiono.
Ta sama sekcja perlrecharclass sugeruje również inne podejścia, które nie obrażą sprzeciwu nauczycieli języków obcych przed podwójnymi negatywami.
Poza regułami ustawień regionalnych i Unicode lub gdy /aprzełącznik działa, „ \spasuje [\t\n\f\r ]i, począwszy od Perla v5.18, pionowa karta \cK”. Odrzuć \ri \npozostaw, /[\t\f\cK ]/aby dopasować białe znaki, ale nie nową linię.
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;}
Inne aplikacje
Sztuczka podwójnie ujemna jest również przydatna do dopasowywania znaków alfabetycznych. Pamiętaj, że \wpasuje do „znaków słownych”, znaków alfabetycznych oraz cyfr i podkreślników. My, brzydcy Amerykanie, czasami chcemy to napisać, powiedzmy,
if(/[A-Za-z]+/){...}
ale podwójnie ujemna klasa znaków może respektować ustawienia regionalne:
if(/[^\W\d_]+/){...}
Wyrażenie „znak słowa, ale nie cyfry lub podkreślenia” w ten sposób jest nieco nieprzejrzyste. Klasa znaków POSIX komunikuje zamiar bardziej bezpośrednio
if(/[[:alpha:]]+/){...}
lub z właściwością Unicode, jak sugerował szbalint
Sprytne, ale zachowanie jest bardzo zaskakujące i nie rozumiem, jak jest mniej niezręczne.
Qwertie,
7
@Qwertie: co jest zaskakujące? Mniej niezręczny niż co?
ysth
9
Wyjątkowo okropny.
9
To jest bardzo dobre. Zgodnie z żądaniem dopasowujesz białe znaki (nie tylko niektóre białe znaki) i wykluczasz znak przejścia do nowego wiersza. Twoje rozwiązanie nie dotyczy samego pytania: „jakie są znaki białych znaków”, jak nie powinno. Właśnie tego szukałem. (Jak zauważył @Rory, a „nowej linii” może także zawierać \r, np na Windows, więc uważają, najtańsza te z meczu jak dobrze: /[^\S\r\n]/)
Timo
1
Z pewnością zaspokoi to potrzeby PO i praktycznie każdego, kto szuka tego pytania (w każdym razie anglojęzyczni). Ale to wciąż zła odpowiedź. Po prostu nie ma usprawiedliwienia dla korzystania z tego rozwiązania, gdy \hjest ono dostępne.
Ten wyrażenie regularne jest bezpieczniejsze niż /[^\S\n]/bez \r. Moje rozumowanie jest takie, że Windows używa \r\nnowych linii, a Mac OS 9 używany \r. Jest mało prawdopodobne, aby znaleźć \rbez \ndzisiejszych czasach, ale jeśli nie znajdziesz, to nie może oznaczać niczego oprócz znaku nowej linii. Zatem, ponieważ \rmoże oznaczać nowy wiersz, powinniśmy go również wykluczyć.
Możesz być zaskoczony, jak wiele programów nadal używa „\ r” do zakończenia linii. Czasami zajęło mi trochę czasu, aby zorientować się, że mój problem polega na tym, że plik ich używał. Albo że używał kodowania znaków MacRoman ...
mivk
2
wygląda na to, że @Greg po raz pierwszy „źle” to zmieniło i nie przyznało ci uznania. Właśnie dlatego tutaj jestem entuzjastą.
Andre Elrico
14
Poniższy regex pasowałby do białych spacji, ale nie do nowego znaku linii.
Nie wiem, dlaczego ludzie nie wspomnieli o klasie znaków POSIX, [[:blank:]]która pasuje do poziomych białych znaków ( spacji i tabulatorów ). Ta klasa chracter POSIX będzie działać na BRE ( Basic REgular Expressions ), ERE ( Extended Regular Expression ), PCRE ( Perl Compatible Regular Expression ).
To, czego szukasz, to blankklasa znaków POSIX . W Perlu jest określany jako:
[[:blank:]]
w Javie (nie zapomnij włączyć UNICODE_CHARACTER_CLASS):
\p{Blank}
W porównaniu z podobnym \h, POSIX blankjest obsługiwany przez kilka kolejnych silników wyrażeń regularnych ( odniesienie ). Główną zaletą jest to, że jego definicja została ustalona w załączniku C: Właściwości kompatybilności wyrażeń regularnych Unicode i standard we wszystkich odmianach regularnych obsługujących Unicode. (Na przykład w Perlu \hdecyduje się dodatkowo dołączyć MONGOLIAN VOWEL SEPARATOR.) Jednak argumentem przemawiającym za \htym jest to, że zawsze wykrywa znaki Unicode (nawet jeśli silniki nie zgadzają się co do tego), podczas gdy klasy znaków POSIX są często domyślnie ASCII -tylko (jak w Javie).
Problem polega jednak na tym, że nawet trzymanie się Unicode nie rozwiązuje problemu w 100%. Rozważ następujące znaki, które nie są uważane za białe znaki w Unicode:
Wyżej wymieniony mongolski separator samogłosek nie jest zawarty z tego, co prawdopodobnie jest dobrym powodem. Wraz z 200C i 200D występuje w słowach (AFAIK), a zatem łamie kardynalną zasadę, której przestrzegają wszystkie inne białe znaki: możesz za jej pomocą tokenizować. Są bardziej jak modyfikatory. Jednak ZERO WIDTH SPACE, WORD JOINERorazZERO WIDTH NON-BREAKING SPACE (jeśli jest stosowany jako inny niż znak kolejności bajtów) pasuje do reguły białe znaki w mojej książce. Dlatego włączam je do mojej poziomej klasy białych znaków.
W Javie:
static public final String HORIZONTAL_WHITESPACE ="[\\p{Blank}\\u200B\\u2060\\uFFEF]"
Musisz dodać odpowiednie flagi kompilacji wyrażenia regularnego do kompilacji Java i uruchomić Javę 7 lub nowszą. W każdym razie pytanie nie dotyczyło w ogóle Javy ani PCRE, więc jest to nieistotne.
tchrist
@ tchrist Dziękujemy za zwrócenie na to uwagi. Zaktualizuję swoją odpowiedź. Nie zgadzam się jednak, że moja odpowiedź jest nieistotna. Nieistotne jest to, że perlznacznik w pierwotnym pytaniu.
Aleksandr Dubinsky
1
@AleksandrDubinsky, \ p {Blank} nie jest obsługiwany w JavaScript, więc zdecydowanie nie jest „standardem dla wszystkich smaków wyrażenia regularnego” -1
Valentin Vasilyev
Najbardziej pouczające. Niepokoi mnie to, że nie istnieje ogólna i kompletna krótka klasa znaków „pozioma biała spacja” i że [\p{Blank}\u200b\u180e]wymagane są horrory . Trzeba przyznać, że separator samogłosek nie jest uważany za znak spacji, ale dlaczego nie ma spacji o zerowej szerokości w klasach takich jak \si \p{Blank}, bije mnie.
Timo,
Dalsze działania: czytam, że oba są uważane za „neutralne dla granic”, chociaż to nie wyjaśnia, dlaczego .
Timo,
-4
m/ /gpo prostu daj miejsce / /, a zadziała. Lub użyj \S- zastąpi wszystkie znaki specjalne, takie jak tabulator, znaki nowej linii, spacje i tak dalej.
[\r\f]
.Odpowiedzi:
Perl wersje 5.10 i później zależne wsparcie klas postaci pionowej i poziomej,
\v
a\h
, jak również ogólny spacje klasa znaków\s
Najczystszym rozwiązaniem jest użycie poziomej klasy znaków białych znaków
\h
. Spowoduje to dopasowanie tabulacji i spacji z zestawu ASCII, nierozdzielania spacji z rozszerzonego ASCII lub dowolnego z tych znaków UnicodePionowa przestrzeń wzór
\v
jest mniej przydatna, ale pasuje do tych znakówIstnieje siedem pasujących znaków pionowych białych znaków
\v
i osiemnaście pasujących znaków poziomych\h
.\s
dopasowuje dwadzieścia trzy znakiWszystkie znaki białych znaków są pionowe lub poziome, bez nakładania się, ale nie są odpowiednimi podzestawami, ponieważ
\h
również pasują do U + 00A0 BEZ PRZERWU, a\v
także pasują do U + 0085 NASTĘPNA LINIA, z których żaden nie jest dopasowany\s
źródło
\h
działa tylko w obsługiwanych językachPCRE
.[[:blank:]]
nie pasuje do spacji bez przerwy -
lub"\xA0"
\h
działało idealnie w moim przypadku użycia, który szukał / zamienił w Notepad ++ na co najmniej 1 ciągłym spacji nie nowej linii. Nic innego (proste) nie działało.\h
nieco niestandardowy, to jego włączenieMONGOLIAN VOWEL SEPARATOR
. Unicode nie uważa tego za spację. Z tego powodu Perl\h
różni się od POSIXblank
([[:blank:]]
w Perlu,\p{Blank}
w Javie) i Java 8\h
. Trzeba przyznać, że to przypadek na krawędzi.Użyj podwójnie ujemnego:
Oznacza to, że nie-spacja (duża litera S uzupełnia) lub zwrot-przewóz lub brak nowej linii. Dystrybucja zewnętrzna nie ( tj . Uzupełniająca
^
w klasie postaci) z prawem De Morgana , jest to równoważne z „białymi spacjami, ale nie znakiem powrotu karetki lub znakiem nowej linii”. Włączenie zarówno wzorca, jak\r
i\n
wzorca poprawnie obsługuje wszystkie konwencje nowego wiersza Uniksa (LF), klasycznego Mac OS (CR) i DOS-ish (CR LF) .Nie musisz mi wierzyć na słowo:
Wynik:
Zwróć uwagę na wyłączenie karty pionowej, ale zostało to rozwiązane w wersji 5.18 .
Przed zbyt surowym sprzeciwem dokumentacja Perla używa tej samej techniki. Przypis w sekcji „Białe znaki” w perlrecharclass brzmi:
Ta sama sekcja perlrecharclass sugeruje również inne podejścia, które nie obrażą sprzeciwu nauczycieli języków obcych przed podwójnymi negatywami.
Poza regułami ustawień regionalnych i Unicode lub gdy
/a
przełącznik działa, „\s
pasuje[\t\n\f\r ]
i, począwszy od Perla v5.18, pionowa karta\cK
”. Odrzuć\r
i\n
pozostaw,/[\t\f\cK ]/
aby dopasować białe znaki, ale nie nową linię.Jeśli twój tekst to Unicode, użyj kodu podobnego do podanego poniżej, aby zbudować wzór z tabeli w wyżej wymienionej sekcji dokumentacji .
Inne aplikacje
Sztuczka podwójnie ujemna jest również przydatna do dopasowywania znaków alfabetycznych. Pamiętaj, że
\w
pasuje do „znaków słownych”, znaków alfabetycznych oraz cyfr i podkreślników. My, brzydcy Amerykanie, czasami chcemy to napisać, powiedzmy,ale podwójnie ujemna klasa znaków może respektować ustawienia regionalne:
Wyrażenie „znak słowa, ale nie cyfry lub podkreślenia” w ten sposób jest nieco nieprzejrzyste. Klasa znaków POSIX komunikuje zamiar bardziej bezpośrednio
lub z właściwością Unicode, jak sugerował szbalint
źródło
\r
, np na Windows, więc uważają, najtańsza te z meczu jak dobrze:/[^\S\r\n]/
)\h
jest ono dostępne.Odmiana odpowiedzi Grega, która obejmuje również zwrot karetki:
Ten wyrażenie regularne jest bezpieczniejsze niż
/[^\S\n]/
bez\r
. Moje rozumowanie jest takie, że Windows używa\r\n
nowych linii, a Mac OS 9 używany\r
. Jest mało prawdopodobne, aby znaleźć\r
bez\n
dzisiejszych czasach, ale jeśli nie znajdziesz, to nie może oznaczać niczego oprócz znaku nowej linii. Zatem, ponieważ\r
może oznaczać nowy wiersz, powinniśmy go również wykluczyć.źródło
Poniższy regex pasowałby do białych spacji, ale nie do nowego znaku linii.
PRÓBNY
Jeśli chcesz również dodać znak powrotu karetki, dodaj go
\r
wraz z|
operatorem wewnątrz przeczącej perspektywy.PRÓBNY
Dodaj
+
po grupie, która nie została przechwycona, aby dopasować jedną lub więcej białych spacji.PRÓBNY
Nie wiem, dlaczego ludzie nie wspomnieli o klasie znaków POSIX,
[[:blank:]]
która pasuje do poziomych białych znaków ( spacji i tabulatorów ). Ta klasa chracter POSIX będzie działać na BRE ( Basic REgular Expressions ), ERE ( Extended Regular Expression ), PCRE ( Perl Compatible Regular Expression ).PRÓBNY
źródło
To, czego szukasz, to
blank
klasa znaków POSIX . W Perlu jest określany jako:w Javie (nie zapomnij włączyć
UNICODE_CHARACTER_CLASS
):W porównaniu z podobnym
\h
, POSIXblank
jest obsługiwany przez kilka kolejnych silników wyrażeń regularnych ( odniesienie ). Główną zaletą jest to, że jego definicja została ustalona w załączniku C: Właściwości kompatybilności wyrażeń regularnych Unicode i standard we wszystkich odmianach regularnych obsługujących Unicode. (Na przykład w Perlu\h
decyduje się dodatkowo dołączyćMONGOLIAN VOWEL SEPARATOR
.) Jednak argumentem przemawiającym za\h
tym jest to, że zawsze wykrywa znaki Unicode (nawet jeśli silniki nie zgadzają się co do tego), podczas gdy klasy znaków POSIX są często domyślnie ASCII -tylko (jak w Javie).Problem polega jednak na tym, że nawet trzymanie się Unicode nie rozwiązuje problemu w 100%. Rozważ następujące znaki, które nie są uważane za białe znaki w Unicode:
U + 180E MONGOLIJSKI SEPARATOR GŁÓWNY
U + 200B ZERO WIDTH SPACE
U + 200C SZEROKOŚĆ ZEROWA NIE JOINER
ŁĄCZNIK SZEROKOŚCI U + 200D
U + 2060 WORD JOINER
U + FEFF ZERO WIDTH PRZESTRZEŃ NIEWYŁUSZAJĄCA
Zaczerpnięte z https://en.wikipedia.org/wiki/White-space_character
Wyżej wymieniony mongolski separator samogłosek nie jest zawarty z tego, co prawdopodobnie jest dobrym powodem. Wraz z 200C i 200D występuje w słowach (AFAIK), a zatem łamie kardynalną zasadę, której przestrzegają wszystkie inne białe znaki: możesz za jej pomocą tokenizować. Są bardziej jak modyfikatory. Jednak
ZERO WIDTH SPACE
,WORD JOINER
orazZERO WIDTH NON-BREAKING SPACE
(jeśli jest stosowany jako inny niż znak kolejności bajtów) pasuje do reguły białe znaki w mojej książce. Dlatego włączam je do mojej poziomej klasy białych znaków.W Javie:
źródło
perl
znacznik w pierwotnym pytaniu.[\p{Blank}\u200b\u180e]
wymagane są horrory . Trzeba przyznać, że separator samogłosek nie jest uważany za znak spacji, ale dlaczego nie ma spacji o zerowej szerokości w klasach takich jak\s
i\p{Blank}
, bije mnie.m/ /g
po prostu daj miejsce/ /
, a zadziała. Lub użyj\S
- zastąpi wszystkie znaki specjalne, takie jak tabulator, znaki nowej linii, spacje i tak dalej.źródło