regex - regular - 匹配空格但不包含換行符




regular expression (4)

Perl版本5.10和更高版本支持附屬的垂直和水平字符類\v\h以及通用空白字符類\s

最乾淨的解決方案是使用水平空白字符類\h 。 這將匹配ASCII集中的製表符和空格,非擴展ASCII空間或任何這些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

垂直空間模式\v不太有用,但匹配這些字符

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

有7個垂直空格字符匹配\v和18個水平匹配\h\s匹配二十三個字符

所有空格字符都是垂直水平的 ,沒有重疊,但它們不是合適的子集,因為\h也匹配U + 00A0無間隔空格,並且\v也匹配U + 0085 NEXT LINE,它們都不匹配\s

我有時想匹配空白而不是換行符。

到目前為止,我一直在訴諸於[ \t] 。 有沒有一個尷尬的方式?


m/ /g只是給/ /空間,它會起作用。 或者使用\S - 它會替換所有特殊字符,如製表符,換行符,空格等等。


你在找什麼是POSIX blank字符類。 在Perl中它被引用為:

[[:blank:]]

在Java中(不要忘記啟用UNICODE_CHARACTER_CLASS ):

\p{Blank}

與類似的\h相比,POSIX blank支持更多的正則表達式引擎( reference )。 一個主要的好處是它的定義在Unicode正則表達式的附錄C:兼容性屬性和所有支持Unicode的正則表達式風格的標準中得到修復。 (例如,在Perl中, \h選擇另外包含MONGOLIAN VOWEL SEPARATOR )。然而,支持\h的論點是它總是檢測Unicode字符(即使引擎不同意哪個),而POSIX字符類通常默認只有ASCII(如在Java中)。

但問題是,即使堅持Unicode也不能解決問題100%。 考慮以下在Unicode中不被認為是空白的字符:

前面提到的蒙古元音分隔符不包括在內,可能是一個很好的理由。 它與200C和200D一起出現在單詞(AFAIK)中,因此打破了所有其他空白符合的基本規則:您可以用它來標記化。 他們更像修飾語。 但是, ZERO WIDTH SPACEWORD JOINERZERO WIDTH NON-BREAKING SPACE (如果它不是字節順序標記)適用於我的書中的空白規則。 因此,我將它們包含在我的水平空白字符類中。

在Java中:

static public final String HORIZONTAL_WHITESPACE = "[\\p{Blank}\\u200B\\u2060\\uFFEF]"

使用雙重否定:

/[^\S\n]/

為了避免在perlport中關於\r\n映射提出的平台差異:

/[^\S\x0a\x0d]/

也就是說,不是非空白或非新行,以及排除CR和NL的模式類似。

De Morgan的法則分配外部不是( 在角色類中的補充),這相當於“空白而不是回車而不是換行”,但不要聽我說:

#! /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";
}

輸出:

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

請注意排除垂直選項卡,但這在v5.18中解決

這個技巧對於匹配字母字符也很方便。 請記住\w匹配“單詞字符”,字母字符,但也包含數字和下劃線。 我們醜陋的美國人有時想寫它,比如說,

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

但是雙重否定的字符類可以尊重語言環境:

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

這有點不透明,所以POSIX角色類可能會更好地表達意圖

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

或者按照szbalint建議

if (/^\p{Letter}+$/) { ... }






perl