2016-11-07 13 views
0

私は2つの正規表現を持っています。最初のものと一致するものがあれば、2番目のものすべてを削除したい。基本的には、すでにマッチしていたものは何も照合できません。例:ラクダの犯罪ケアクールメディアメルト家:他の正規表現のマッチ内に置かれた正規表現のマッチを削除する

まず正規表現(太字) - meme

の検索結果を見つけた - c\w+c

で始まる単語の第二の正規表現(下線)が見つかりました

meのc単語も一致しています。私が欲しい欲しいのです:ラクダ犯罪ケアクールメディアメルトホーム第二の正規表現の

二つの結果は、最初の正規表現の結果であり、私はそれらを削除するか、単にすべてでそれらを一致していません。ここで私が試したことは次のとおりです。

このコードでは、両方のリストの一致をすべてリストに保存してから、リストの最初のリストと一致する2番目のリストを削除しようとします。

これは機能しないだけでなく、非常に効率的であるかどうかはわかりません。これは私の状況の単純化されたバージョンであり、より多くの正規表現と大きなテキストが含まれていることに注意してください。 Iterablesはグアバ出身です。

+0

あなたがしようとしていることについてはっきりしていません。あなたは文字列からそれらを削除しようとしていますので、結果は '' cal cri care cool medium melt home ''ですか?もしそうなら、あなたの質問はこれではっきりしません。また、実際に文字列から何かを削除するコードはありません。また、Iterablesとは何ですか?これは標準のJavaライブラリにはないので、それは何ですか? Apache?グアバ?私はその情報なしで何が起こっているのかは分かりませんが、 'removeIf'があなたが作成した' List'からペアのうちの1つを削除しているようです。それは文字列から何も削除していません。 – ajb

+0

また、最初のパターンでは、単語の先頭にあるかどうかに関係なく、「c」が見つかります。 – ajb

+0

@ajbすべてのマッチがリストに保存されました。私はそれらから2番目の正規表現リストから削除しようとしています。 IterablesはGuavaから、私はJava 8関数を使用できませんでした –

答えて

2

まずあなたが一つに両方の式をマージこのような何かを達成することができます。

(^c\w+)|\s(c\w+)|(\w*me\w*) 

あなたはこの正規表現にマッチした場合、すべての試合には、いくつかの単語の文字や「私」を含む単語に続く「C」で始まる単語のいずれかになります。すべてのマッチについて、グループ「 (1)または(2)」は「c」で始まる単語を示し、 (3)は「me」を含む単語を示します。

ただし、あなたは単語の区切り文字、この場合は\ s文字を知っています。

例コード:

String text = "camel crime care cool medium melt home"; 

    final Pattern PATTERN = Pattern.compile("(^c\\w+)|\\s(c\\w+)|(\\w*me\\w*)"); 

    // Save all matches 
    List<String> wordsStartingWithC = new ArrayList<>(); 
    List<String> wordsIncludingMe = new ArrayList<>(); 

    for (Matcher m = PATTERN.matcher(text); m.find();) { 
     if(m.group(1) != null) { 
      wordsStartingWithC.add(m.group(1)); 
     } else if(m.group(2) != null) { 
      wordsStartingWithC.add(m.group(2)); 
     } else if(m.group(3) != null) { 
      wordsIncludingMe.add(m.group(3)); 
     } 
    } 

    System.out.println(wordsStartingWithC); 
    System.out.println(wordsIncludingMe); 

私は多少異なるアプローチを取ることによって、これを簡素化するためにお勧めします。 単語リミッタ、つまり空白文字を知っているように思われるので、元の文字列を分割するだけですべての単語のコレクションを得ることができます。

String[] words = "camel crime care cool medium melt home".split(" "); 

次に、これらのすべてを繰り返し処理します。

for(String word: words) {     
    if(word.startsWith("c")) { 
     // put in your list for words starting with "c" 
    } else if (word.contains("me")) { 
     // put in your list for words containing "me" 
    } 
} 

2つ目のif文は、最初のものが失敗した場合にのみ実行されるため、重複したエントリがない2つのリストになります。

+0

私はmatcher.group()が正規表現内のどのグループにマッチをしたかを考えて自分のコードに最初のアプローチを使用しました。例えば、一致が 'c 'で始まる単語であった場合、グループ1は一致をしたので1を返します。しかし、そうではありません。あなたはこの価値を得る方法を知っていますか? –

+0

@ Croutonix私は最初のアプローチをどのように働かせるかの例を追加しました。私は現在IDEを持っていないので、コンパイルしてtutorialspointで実行してみたところ、うまくいきました。 – Endzeit

1

2つのRegexesを組み合わせることはできませんか?例えば、cmeは、このコードで1正規表現を使用して見つけることができます:

((?<=c)|(?<=c\w)|(?<=c\w{2})|(?<=c\w{3})|(?<=c\w{4})|(?<=c\w{5}))me 

はここでそれをチェックアウト:すべてのhttps://regex101.com/r/bfNkvF/2

+0

正規表現で2つの別々のことをする必要があるので、このカントの作業はできません。これで私はそれらを区別できません。(可能でしょうか) –

+0

いいえ、グループや別の正規表現を使用しない限りできません。 – Ibrahim