2013-05-29 10 views
21

はのは、私は次の文字列を持っているとしましょう:私はname=valueのすべての一致を検索し、文字列全体がパターンに一致することを確認する正規表現の式を反復するためにどのように

name1=gil;name2=orit; 

だから私は次のようでした:

  1. 全体のパターンは私が望むものと一致していることを確認してください。パターンname=value

    Pattern p = Pattern.compile("(\\w+)=(\\w+);"); 
    Matcher m = p.matcher(line); 
    while (m.find()) { 
        map.put(m.group(1), m.group(2)); 
    } 
    

オーバー

Pattern p = Pattern.compile("^((\\w+)=(\\w+);)*$"); 
Matcher m = p.matcher(line); 
if (!m.matches()) { 
    return false; 
} 
  • 反復は1つの正規表現でこれを行うには、いくつかの方法はありますか?

  • 答えて

    27

    あなたがで1つの正規表現と一致する上で検証し、反復することができます置くことで一致した(例えばname1=x;;name2=y;)の間には、比類のない文字が含まれていないの確保

    • 正規表現の先頭の\Gは、"the end of the previous match"を意味します。

    • 文字列の長さをMatcher.end()と比較することで、最後の文字列の最後に達したかどうかを確認します。最後の文字の後にオフセットが返されます。

    ような何か:

    String line = "name1=gil;name2=orit;"; 
    Pattern p = Pattern.compile("\\G(\\w+)=(\\w+);"); 
    Matcher m = p.matcher(line); 
    int lastMatchPos = 0; 
    while (m.find()) { 
        System.out.println(m.group(1)); 
        System.out.println(m.group(2)); 
        lastMatchPos = m.end(); 
    } 
    if (lastMatchPos != line.length()) 
        System.out.println("Invalid string!"); 
    

    Live demoを。


    いくつかの言語を使用すると、
    ^((\\w+)=(\\w+);)*$から直接個々の一致を反復することが可能かもしれないが、私はあなたがJavaでこれを行うことができます信じていません。

    2

    「^」と「$」が期待通りに機能するには、複数モードを有効にする必要があります。

    Pattern p = Pattern.compile("^(?:(\\w+)=(\\w+);)*$", Pattern.MULTILINE); 
    while (m.find()) { 
        for (int i = 0; i < m.groupCount() - 2; i += 2) { 
         map.put(m.group(i + 1), m.group(i + 2)); 
        } 
    } 
    

    コメント右、あなたはまだ、各ラインのマッチンググループを反復処理し、外側のグループに非キャプチャグループ(?:...)をしなければなりません。

    +0

    デフォルトではregexエンジンは複数行のmode.didでマッチしますdotallオプションを使用したいと思っています!問題の例では正規表現は動作しません.. – Anirudha

    +0

    @Anirudh:デフォルトでは、マルチラインモードはJavaでは有効になっていません。 DOTALLオプションはここでは役に立たないでしょう。 – nhahtdh

    +0

    -1、これは質問に答えないためです。 – nhahtdh

    0
    String example = "name1=gil;name2=orit;"; 
    Pattern pattern = Pattern.compile("((name[0-9]+?=(.+?);))+?"); 
    Matcher matcher = pattern.matcher(example); 
    // verifies full match 
    if (matcher.matches()) { 
        System.out.println("Whole String matched: " + matcher.group()); 
        // resets matcher 
        matcher.reset(); 
        // iterates over found 
        while (matcher.find()) { 
         System.out.println("\tFound: " + matcher.group(2)); 
         System.out.println("\t--> name is: " + matcher.group(3)); 
        } 
    } 
    

    出力:

    Whole String matched: name1=gil;name2=orit; 
        Found: name1=gil; 
        --> name is: gil 
        Found: name2=orit; 
        --> name is: orit 
    
    +1

    これは本当に1正規表現ですが、入力文字列( 'matches()に1回、' find()でループに1回)を2回渡す必要があります。 – nhahtdh

    +0

    @nhahtdhそうです。しかし、ここでは「1パス」の制限は認識されていませんでした。 – Mena

    +1

    実際の制限ではなく、パス数の点でOPの現在のソリューションと大きく異なるわけではありません。 – nhahtdh

    関連する問題