Dopasuj białe znaki, ale nie nowe linie

Czasami chcę dopasować białe znaki, ale nie nową linię.

Do tej pory uciekałem się do [ \t]. Czy jest mniej niezręczny sposób?

 207
Author: Borodin, 2010-08-12

6 answers

Wersje Perla 5.10 i późniejsze obsługują dodatkowe pionowe i poziome klasy znaków, \v i \h, a także ogólną klasę znaków spacji \s

Najczystszym rozwiązaniem jest użycie klasy znaków poziomej białej spacji \h. Ta opcja jest zgodna z tabulatorem i spacją z zestawu ASCII, spacją niełamliwą z rozszerzonego ASCII lub którymkolwiek 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

Przestrzeń pionowa wzór \v jest mniej użyteczny, ale pasuje znaki te

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

Jest siedem pionowych znaków, które pasują \v i osiemnaście poziomych, które pasują \h. \s pasuje do dwudziestu trzech znaków

Wszystkie znaki spacji są albo pionowe lub poziome bez nakładania się, ale nie są poprawnymi podzbiorami, ponieważ \h Również pasuje do U+00A0 bez przerwy, a \v pasuje również do U+0085 następnego wiersza, z których żaden nie jest dopasowany przez \s

 142
Author: Borodin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-07-06 12:06:04

Użyj podwójnego negatywu:

/[^\S\n]/

Aby uniknąć różnic między platformami ostrzegany w perlport odnośnie mapowania \r i \n:

/[^\S\x0a\x0d]/

To znaczy Nie-Nie-whitespace lub nie-newline i podobne dla wzorca, który wyklucza CR i NL.

Rozdzielając zewnętrzne not ( tj., dopełniające ^ w klasie znaków) z prawem De Morgana , jest to równoważne "whitespace and not carriage return and not newline", ale nie wierz mi na słowo:

#! /usr/bin/env perl

use strict;
use warnings;

use 5.005;  # for qr//

my $ws_not_nl = qr/[^\S\x0a\x0d]/;

for (' ', '\f', '\t', '\r', '\n') {
  my $qq = qq["$_"];
  printf "%-4s => %s\n", $qq,
    (eval $qq) =~ $ws_not_nl ? "match" : "no match";
}

Wyjście:

" "  => match
"\f" => match
"\t" => match
"\r" => no match
"\n" => no match

Zwróć uwagę na wykluczenie zakładki pionowej, ale jest to zaadresowane w wersji 5.18.

Ta sztuczka jest również przydatna do dopasowania znaków alfabetycznych. Pamiętaj, że \w pasuje do "znaków słownych", znaków alfabetycznych, ale również cyfr i podkreślenia. My brzydcy-Amerykanie czasami chcemy napisać to jako, powiedzmy,

if (/^[A-Za-z]+$/) { ... }

Ale Podwójna-negatywna klasa znaków może respektować locale:

if (/^[^\W\d_]+$/) { ... }

Jest to nieco nieprzezroczyste, więc klasa znaków POSIX może być lepsza w wyrażaniu intencji

if (/^[[:alpha:]]+$/) { ... }

Lub jako szbalint zasugerował

if (/^\p{Letter}+$/) { ... }
 276
Author: Greg Bacon,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:54:59

Wariacja na temat odpowiedzi Grega , która również zawiera zwroty karetki:

/[^\S\r\n]/

Ten regex jest bezpieczniejszy niż /[^\S\n]/ z no \r. Moim rozumowaniem jest to, że Windows używa \r\n dla nowych linii, A Mac OS 9 używa \r. Jest mało prawdopodobne, aby znaleźć \r bez \n w dzisiejszych czasach, ale jeśli go znajdziesz, nie może to oznaczać nic innego jak nowy wiersz. Tak więc, ponieważ \r może oznaczać nową linię, powinniśmy ją również wykluczyć.

 38
Author: Rory O'Kane,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:02:47

To, czego szukasz, to klasa znaków POSIX blank. W Perlu określa się go jako:

[[:blank:]]

W Javie (nie zapomnij włączyć UNICODE_CHARACTER_CLASS):

\p{Blank}

W porównaniu do podobnego \h, POSIX blank jest obsługiwany przez kilka silników regex (reference ). Główną korzyścią jest to, że jego definicja jest ustalona w załączniku C: Właściwości kompatybilności wyrażeń regularnych Unicode i standard dla wszystkich wyrażeń regex, które obsługują Unicode. (Np. w Perlu, \h wybiera dodatkowo MONGOLIAN VOWEL SEPARATOR.) Jednak argumentem przemawiającym za \h jest to, że zawsze wykrywa znaki Unicode (nawet jeśli silniki nie zgadzają się co do których), podczas gdy klasy znaków POSIX są często domyślnie tylko ASCII (jak w Javie).

Ale problem polega na tym, że nawet trzymanie się Unicode nie rozwiązuje problemu w 100%. Rozważmy następujące znaki, które nie są uważane za białe znaki w Unicode:

Wspomniany mongolski separator samogłosek nie jest uwzględniony, co prawdopodobnie jest dobrym powodem. Występuje wraz z 200C i 200D w obrębie słów (AFAIK) oraz dlatego łamie kardynalną zasadę, której przestrzegają wszystkie inne białe znaki: możesz je tokenizować. Są bardziej jak modyfikatory. Jednakże, ZERO WIDTH SPACE, WORD JOINER, i ZERO WIDTH NON-BREAKING SPACE (jeśli jest używany jako inny niż znak kolejności bajtów) pasują do reguły białych znaków w mojej książce. Dlatego włączam je do mojej klasy znaków poziomych whitespace.

W Języku Java:

static public final String HORIZONTAL_WHITESPACE = "[\\p{Blank}\\u200B\\u2060\\uFFEF]"
 10
Author: Aleksandr Dubinsky,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-02-03 19:22:59

Poniższy regex będzie pasował do białych spacji, ale nie do znaku nowej linii.

(?:(?!\n)\s)

DEMO

Jeśli chcesz dodać również powrót karetki, dodaj \r z operatorem | wewnątrz negatywnego spojrzenia.

(?:(?![\n\r])\s)

DEMO

Dodaj + po grupie nie przechwytywającej, aby dopasować jedną lub więcej białych spacji.

(?:(?![\n\r])\s)+

DEMO

Nie wiem, dlaczego nie wspomnieliście o klasie znaków POSIX [[:blank:]], która pasuje dowolne poziome spacje (spacje i tabulatory ). Ta klasa POSIX chracter będzie działać na Bre (podstawowe wyrażenia regularne), ERE (Rozszerzone Wyrażenie regularne), PCRE (zgodne z Perlem Wyrażenie regularne).

DEMO

 8
Author: Avinash Raj,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-11-08 00:31:43

m/ /g po prostu daj spację w / / i będzie działać. Lub użyj \S - zastąpi wszystkie znaki specjalne, takie jak tab, nowe linie, spacje i tak dalej.

 -4
Author: saiprathapreddy.obula,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-08-13 01:47:28