改行ではなく空白に一致させたい場合があります。
これまでのところ、私は頼りにしてきました[ \t]
。それほど厄介な方法はありませんか?
改行ではなく空白に一致させたい場合があります。
これまでのところ、私は頼りにしてきました[ \t]
。それほど厄介な方法はありませんか?
回答:
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
23文字に一致
すべての空白文字は、垂直または水平で重複はありませんが、\h
U + 00A0 NO-BREAK SPACEに\v
も一致し、U + 0085 NEXT LINEにも一致するため、適切なサブセットではありません。\s
\h
をサポートする言語でのみ動作しますPCRE
。
[[:blank:]]
がノーブレークスペースと一致しない場合を除いて-
または"\xA0"
\h
Notepad ++で1つ以上の連続する非改行スペースで検索/置換を行っていた私のユースケースでは、これが完全に機能したことに言及したいと思います。他には何も(単純な)機能しませんでした。
\h
少し非標準になっているのは、が含まれているためですMONGOLIAN VOWEL SEPARATOR
。Unicodeは空白を考慮しません。そのため、Perl \h
はPOSIX blank
([[:blank:]]
Perl、\p{Blank}
Java)およびJava 8とは異なり\h
ます。確かに、それはエッジケースです。
ダブルネガティブを使用:
/[^\S\r\n]/
つまり、not-not-whitespace(大文字のSは補数)またはnot-carriage-returnまたはnot-newlineです。アウターnot(つまり、^
文字クラスでの補完)をドモーガンの法則で分配すると、これは「空白文字ですが、キャリッジリターンや改行ではありません」と同等です。パターンとパターンの両方\r
を含めると\n
、すべてのUnix(LF)、クラシックMac OS(CR)、およびDOS風(CR LF)の改行規則が正しく処理されます。
私の言葉をそれで理解する必要はありません:
#! /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";
}
出力:
"" =>一致 "\ f" =>一致 "\ t" =>一致 "\ r" =>一致しません "\ n" =>一致しません
垂直タブの除外に注意してください。ただし、これはv5.18で対処されています。
厳しく反対する前に、Perlのドキュメントでは同じ手法を使用しています。で脚注perlrecharclassの「空白」セクションには、読み込み
Perl v5.18より前
\s
は、垂直タブと一致しませんでした。[^\S\cK]
(あいまいに)\s
従来の方法と一致します。
perlrecharclassの同じセクションは、ダブルネガティブに対する言語教師の反対を害しない他のアプローチも示唆しています。
ロケールとUnicodeの規則の外、または/a
スイッチが有効な場合、「\s
一致[\t\n\f\r ]
し、Perl v5.18以降では、垂直タブ\cK
」破棄\r
し\n
て/[\t\f\cK ]/
、一致する空白文字のために残しますが、改行はしません。
テキストがUnicodeの場合は、以下のサブコードと同様のコードを使用して、前述のドキュメントセクションの表からパターンを作成します。
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;
}
ダブルネガティブトリックは、アルファベット文字の照合にも便利です。\w
「単語文字」、アルファベット文字、数字、アンダースコアに一致することを覚えておいてください。私たち醜いアメリカ人は時々それを、たとえば、
if (/[A-Za-z]+/) { ... }
ただし、二重の負の文字クラスはロケールを尊重できます。
if (/[^\W\d_]+/) { ... }
このように「単語の文字で数字やアンダースコアではない」と表現することは、少し不透明です。POSIX文字クラスは意図をより直接的に伝達します
if (/[[:alpha:]]+/) { ... }
またはszbalintが提案するUnicodeプロパティを使用
if (/\p{Letter}+/) { ... }
\r
Windowsなども含まれる可能性があるため、マッチから除外することも検討してください/[^\S\r\n]/
)
\h
利用可能な場合、このソリューションを使用するための言い訳はありません。
キャリッジリターンも含むグレッグの回答のバリエーション:
/[^\S\r\n]/
この正規表現は/[^\S\n]/
noを使用するよりも安全です\r
。私の考えでは、Windowsは\r\n
改行に使用し、Mac OS 9はに使用してい\r
ます。今日\r
なくして見つけることはほとんどあり\n
ませんが、見つけたとしても、改行以外の意味はありません。したがって、\r
は改行を意味する可能性があるため、それも除外する必要があります。
以下の正規表現は空白と一致しますが、改行文字とは一致しません。
(?:(?!\n)\s)
キャリッジリターンを追加する場合も、否定先読み内に演算子を追加\r
し|
ます。
(?:(?![\n\r])\s)
+
非キャプチャグループの後に追加して、1つ以上の空白に一致させます。
(?:(?![\n\r])\s)+
[[:blank:]]
水平方向の空白(スペースとタブ)に一致するPOSIX文字クラスに言及しなかった理由がわかりません。このPOSIX 文字クラスは、BRE(基本正規表現)、ERE(拡張正規表現)、PCRE(Perl互換正規表現)で機能します。)で機能します。
探しているのはPOSIX blank
文字クラスです。Perlでは、次のように参照されます。
[[:blank:]]
Java(有効にすることを忘れないでくださいUNICODE_CHARACTER_CLASS
):
\p{Blank}
類似のものと比較して\h
、POSIX blank
はいくつかの正規表現エンジンでサポートされています(参照)。主な利点は、その定義が付録C:Unicode正規表現の互換性プロパティとUnicodeをサポートするすべての正規表現フレーバーの標準で修正されていることです。(ではPerlは、例えば、\h
さらにすることを選択するにはMONGOLIAN VOWEL SEPARATOR
。)しかし、賛成の引数が\h
、それは常に(エンジンがどの同意しない場合でも)Unicode文字を検出したということです、POSIX文字クラスは、デフォルトのASCIIであることが多い一方、 -only(Javaと同様)。
しかし問題は、Unicodeに固執しても問題を100%解決しないことです。Unicodeの空白とは見なされない以下の文字を考慮してください。
U + 180Eモンゴル語の区切り文字
U + 200Bゼロ幅スペース
U + 200C ZERO WIDTH NON-JOINER
U + 200D ZERO WIDTHジョイナー
U + 2060ワードジョイナー
U + FEFF ZERO WIDTH非破壊スペース
前述のモンゴル語の母音区切りは、おそらく正当な理由で含まれていません。これは、200Cおよび200Dとともに、単語内(AFAIK)で発生するため、他のすべての空白が従う基本的な規則に違反します。これをトークン化できます。それらは修飾子のようなものです。しかし、ZERO WIDTH SPACE
、WORD JOINER
、およびZERO WIDTH NON-BREAKING SPACE
(それがバイトオーダーマーク以外のものとして使用されている場合)、私の本の中で空白のルールに適合し。したがって、横の空白文字クラスに含めます。
Javaの場合:
static public final String HORIZONTAL_WHITESPACE = "[\\p{Blank}\\u200B\\u2060\\uFFEF]"
perl
、元の質問のタグです。
[\p{Blank}\u200b\u180e]
が必要であることを知るのは気がかりです。確かに、母音区切り文字が空白文字と見なされないのは理にかなっていますが、なぜ\s
andのようなクラスにゼロ幅のスペースがないのか\p{Blank}
、私を打ち負かしています。
m/ /g
でスペースを空けるだけで/ /
動作します。または使用\S
—タブ、改行、スペースなどのすべての特殊文字を置き換えます。
[\r\f]
。