2011-01-29 12 views
3

すべての式を正確に1つの空白に一致させたいと思います。現在、私は[^\\s]*\\s[^\\s]*を使用しています。しかし、それはとても良い方法のようには見えません。Java正規表現 - 正確に1つの空白を含む式

+0

はhttp://stackoverflow.com/questions/4304928/unicode-equivalents-for-w-and-b-in-java-regular-に最初の回答を参照してください。 JavaのUnicode空間に関する問題のリストの式。 – maaartinus

答えて

5

どうしてですか?それは、ちょうど少しovercomplicated罰金です:これは、当然のことながら

String s = "one whitespace"; 


public boolean hasOneWhitespace(String s) { 
    int count = 0; 
    for (int i = 0; i < s.length(); i++) { 
     if(s.charAt(i) == ' ') { 
     count++; 
     if (count > 1) return false; 
     } 
    } 
    return count == 1; 
} 

:あなたは正規表現の道を行くしたくない場合は

\\S*\\s\\S* 
+1

これは複数の空白文字にも一致しません。空白文字の前後に "\\ S *"部分が一致しますか? –

+0

もちろん、matches()メソッドで使用されている場合を除きます。 –

+0

Matcher( "").matches() 'はfalseを返します。これをそのまま使用すると、' Pattern.compile( "\\ S * \\ s \\ S *")あなたが意味することは、 "(\\ S * \\ s \\ S *)+"などと一致します。 – maaartinus

0

もう一つの方法は、(可能な性能向上)、それを行うには" "を空白とみなす場合にのみ動作します。タブと改行は機能しません。

+0

ありがとう、しかし私が求めていた正規表現ははるかに大きな正規表現の一部なので、正規表現でなければなりません。私は正規表現のマッチングがパフォーマンスの売春宿だと知っていますが、プログラムするのがずっと簡単です! – ryyst

+1

このコードは最適ではありません。最初の2つのスペースを含む長い文字列の場合、不必要な作業を実行します。私はregexesが悪いとは思わない、その中に最適化がたくさんある。 – maaartinus

+0

@maaartinus:あなたの提案に代わって自分のコードを最適化しました。 – darioo

0

またindexOfでそれをチェックすることができ:

String s = "some text"; 
int indexOf = s.indexOf(' '); 
boolean isOneWhitespace = (indexOf >= 0 && indexOf == s.lastIndexOf(' ')); 
0

使用TRANSLITERATEを。それは独立したテストでなければなりません。あなたが持っている正規表現は、より大きな正規表現と組み合わされていなくても、単一の空白をテストすることはできません。

このテストの正規表現よりも10-20倍高速です。
これはJTRの例である:

String aInput = "This is a test, 123."; 
CharacterReplacer cReplacer = Perl5Parser.makeReplacer("tr[ \\t\\r\\n\\f\\x0B][ \\t\\r\\n\\f\\x0B]"); 
String aResult = cReplacer.doReplacement(aInput); 
int nMatches = cReplacer.getMatches(); 

if (nMatches == 1) { ... } 
1

私は正確に一つの空白ですべての式に一致するようにしたいです。

空白は、Java文字列で発生しているかどうかを見つけるための正しいパターンは次のとおりです。ここで提供

\A[^\u0009\u000A-\u000D\u0020\u0085\u00A0\u1680\u180E\u2000-\u200A\u2028\u2029\u202F\u205F\u3000]*+[\u0009\u000A-\u000D\u0020\u0085\u00A0\u1680\u180E\u2000-\u200A\u2028\u2029\u202F\u205F\u3000][\u0009\u000A-\u000D\u0020\u0085\u00A0\u1680\u180E\u2000-\u200A\u2028\u2029\u202F\u205F\u3000]*+\z 

他の回答が正しく尋ねた質問に答えていません。

すべてのUnicode空白文字と、その年代(Unicodeリリースが最初に登場したもの)と、スペースの問題に関連するバイナリプロパティです。

U+0009 CHARACTER TABULATION 
    \s \h \pC \p{Cc} 
    Age=1.1 HorizSpace Pattern_White_Space Space White_Space 
U+000A LINE FEED (LF) 
    \s \v \R \pC \p{Cc} 
    Age=1.1 Pattern_White_Space Space VertSpace White_Space 
U+000B LINE TABULATION 
    \v \R \pC \p{Cc} 
    Pattern_White_Space Space VertSpace White_Space 
U+000C FORM FEED (FF) 
    \s \v \R \pC \p{Cc} 
    Age=1.1 Pattern_White_Space Space VertSpace White_Space 
U+000D CARRIAGE RETURN (CR) 
    \s \v \R \pC \p{Cc} 
    Age=1.1 Pattern_White_Space Space VertSpace White_Space 
U+0020 SPACE 
    \s \h \pZ \p{Zs} 
    Age=1.1 HorizSpace Pattern_White_Space Space Space_Separator White_Space 
U+0085 NEXT LINE (NEL) 
    \s \v \R \pC \p{Cc} 
    Age=1.1 Pattern_White_Space Space VertSpace White_Space 
U+00A0 NO-BREAK SPACE 
    \s \h \pZ \p{Zs} 
    Age=1.1 HorizSpace Space Space_Separator White_Space 
U+1680 OGHAM SPACE MARK 
    \s \h \pZ \p{Zs} 
    Age=3.0 HorizSpace Space Space_Separator White_Space 
U+180E MONGOLIAN VOWEL SEPARATOR 
    \s \h \pZ \p{Zs} 
    Age=3.0 HorizSpace Space Space_Separator White_Space 
U+2000 EN QUAD 
    \s \h \pZ \p{Zs} 
    Age=1.1 HorizSpace Space Space_Separator White_Space 
U+2001 EM QUAD 
    \s \h \pZ \p{Zs} 
    Age=1.1 HorizSpace Space Space_Separator White_Space 
U+2002 EN SPACE 
    \s \h \pZ \p{Zs} 
    Age=1.1 HorizSpace Space Space_Separator White_Space 
U+2003 EM SPACE 
    \s \h \pZ \p{Zs} 
    Age=1.1 HorizSpace Space Space_Separator White_Space 
U+2004 THREE-PER-EM SPACE 
    \s \h \pZ \p{Zs} 
    Age=1.1 HorizSpace Space Space_Separator White_Space 
U+2005 FOUR-PER-EM SPACE 
    \s \h \pZ \p{Zs} 
    Age=1.1 HorizSpace Space Space_Separator White_Space 
U+2006 SIX-PER-EM SPACE 
    \s \h \pZ \p{Zs} 
    Age=1.1 HorizSpace Space Space_Separator White_Space 
U+2007 FIGURE SPACE 
    \s \h \pZ \p{Zs} 
    Age=1.1 HorizSpace Space Space_Separator White_Space 
U+2008 PUNCTUATION SPACE 
    \s \h \pZ \p{Zs} 
    Age=1.1 HorizSpace Space Space_Separator White_Space 
U+2009 THIN SPACE 
    \s \h \pZ \p{Zs} 
    Age=1.1 HorizSpace Space Space_Separator White_Space 
U+200A HAIR SPACE 
    \s \h \pZ \p{Zs} 
    Age=1.1 HorizSpace Space Space_Separator White_Space 
U+2028 LINE SEPARATOR 
    \s \v \R \pZ \p{Zl} 
    Age=1.1 Pattern_White_Space Space VertSpace White_Space 
U+2029 PARAGRAPH SEPARATOR 
    \s \v \R \pZ \p{Zp} 
    Age=1.1 Pattern_White_Space Space VertSpace White_Space 
U+202F NARROW NO-BREAK SPACE 
    \s \h \pZ \p{Zs} 
    Age=3.0 HorizSpace Space Space_Separator White_Space 
U+205F MEDIUM MATHEMATICAL SPACE 
    \s \h \pZ \p{Zs} 
    Age=3.2 HorizSpace Space Space_Separator White_Space 
U+3000 IDEOGRAPHIC SPACE 
    \s \h \pZ \p{Zs} 
    Age=1.1 HorizSpace Space Space_Separator White_Space 

4つ以外のすべてが、Unicode 1.1の途中から存在していたことに注意してください。 U + 1680 OGHAM SPACE MARK、U + 180E MONGOLIAN VOWEL SEPARATOR、U + 202F NARROW NO-BREAK SPACEがリリース3.0でUnicode Standardに、そしてU + 205F MEDIUM MATHEMATICAL SPACEが3.2リリースで初めて登場しました。その時以来、これ以上追加されていません。

\p{Whitespace}プロパティはUTS#18 RL1.2 “Properties”に準拠するために必要とされる、と\p{space}エイリアスと空白のため\sショートカットが両方UTS#18 RL1.2a “Compatibility Properties”遵守のために必要とされます。

としてはThe Unicode Standard 6.0.0’s Conformance documentで説明した、White_Spaceプロパティは規範性ではなく、有益な、contributatory、または仮特性です。それは規範的な性質であるため、は、Unicode標準に従ってすべてのUnicode文字データを正しく処理するためにこれらの値を使用するように厳密に要求されています()。

j.u.r.Patternには、この点に関してUnicode標準に準拠した機能はありません。実際には、Javaの正規表現は、UTS #18: Unicode Regular Expressionsに記載されている準拠の可能な最低レベルでさえ、必要な要件の半分を満たすことができません。その最小レベルはレベル1で書かれています。

レベル1は、Unicodeのサポートの最小レベルです。 Javaの正規表現は、Unicodeを扱うための不可欠な最低限の要件のも、これらの非常にbarestを満たすことができないのでユニコードを扱うすべての正規表現の実装は、少なくともレベル1

である必要があり、Javaの正規表現は、Unicodeを扱うための最小限有用ではありません。したがって、準拠した動作を作成したい場合は、上記のような明示的な列挙を採用する必要があります。 my pattern-rewriting libraryを使用してください。

+0

彼らは、あなたの空白の定義だけが異なります。あなたの方がいいかもしれませんが、あなたは私が気にしていると思いますか?どのように知っていますか?たぶんあなたはこれを書いている間に新しいものを追加しましたか?しかし、これを指し示す+1。 – maaartinus

+0

@maaartinus:私の空白の定義は、** The Unicode Standard 6.0.0 **です。私はUnicode Character Databaseをよく知っているので、私はそれを見逃すことができなかったことを知っています。私はまた、識別子の安定性ポリシーにも精通しています:*有効なデフォルトのUnicode識別子であるすべての文字列は、Unicodeの後続のすべてのバージョンで有効なデフォルトのUnicode識別子であり続けます。さらに、デフォルト識別子には、Pattern_SyntaxまたはPattern_White_Spaceプロパティの文字は含まれません。* Pattern_White_Spaceプロパティは変更されないことが保証されています。 – tchrist

+0

私はあなたがそれを知っているのを見て、私はちょうどあなたから非常に長い答えを読んでいます。しかし、銃で脅かされない限り、Unicodeクラスの間違ったJava実装についてのこの長い解決策には向かないでしょう。 j.u.r.Patternを書き直すことは、そのような式を使うよりも簡単です。 – maaartinus

0
String[] ss = { " ", "abc", "a bc", "a b c d" }; 
Matcher m = Pattern.compile("^\\S*\\s\\S*$").matcher(""); 
for (String s : ss) 
{ 
    if (m.reset(s).matches()) 
    { 
    System.out.printf("%n>>%s<< OK%n", s); 
    } 
} 

出力:

>> << OK 

>>a bc<< OK