2017-03-23 2 views
1

(もし私がこれに近づいているべきであれば私に間違った方向を教えてください)Javaは入力に対して複数の正規表現パターンをチェックする方法を教えてください。

私は入力と比較したい複数のパターンを持つJavaプログラムを持っています。いずれかのパターンが一致する場合、その値をStringに保存します。私はそれを単一のパターンで動作させることができますが、私は多くを照らし合わせることができるようにしたいと思います。

今、私は入力が一つのパターンと一致するかどうかを確認するためにこれを持っている:入力がTST1234またはabcTST1234たならば、ID =「TST1234」、だから、

Pattern pattern = Pattern.compile("TST\\w{1,}"); 
Matcher match = pattern.matcher(input); 
String ID = match.find()?match.group():null; 

私は複数のパターンを持つようにしたいです以下のように:

:その後、

Pattern pattern = Pattern.compile("TST\\w{1,}"); 
Pattern pattern = Pattern.compile("TWT\\w{1,}"); 
... 

、その後、コレクションにし、入力に対して各1をご確認ください0

List<Pattern> rxs = new ArrayList<Pattern>(); 
rxs.add(pattern); 
rxs.add(pattern2); 

String ID = null; 

for (Pattern rx : rxs) { 
    if (rx.matcher(requestEnt).matches()){ 
     ID = //??? 
    } 
} 

IDの設定方法がわかりません。私は

ID = rx.matcher(requestEnt).group(); 

ID = rx.matcher(requestEnt).find()?rx.matcher(requestEnt).group():null; 

ないこの仕事やどこかのここから行くするの作り方を実際に確認を試みました。どんな助けや提案も感謝しています。ありがとう。

編集:はいパターンは時間とともに変化します。だから、pattenのリストが成長します。

入力の文字列を取得するだけです。つまり、入力がabcTWT123の場合、最初に "TST \ w {1、}"をチェックしてから "TWT \ w {1、}" IDストリングと一致するので "TWT123"に設定されます。第一のパターンが一致したとき

+0

文字列ごとに一致するすべてのパターンをマップに保存しますか?私はあなたの望む最終出力によって少し混乱しています –

+0

あなたの例を考えれば、あなたのパターンを 'Pattern.compile(" T [SW] T \\ w {1、} ");' => match (パターンA | otherB)\\ w {1、} ");' ...良い答えは、どのように多くのパターン、どのように異なっているか、どのように構成可能か動的か...コードを書くときに知られているすべてのパターンがありますか?時間の経過とともに変化しますか? –

+0

はい、パターンは時間とともに変化します。 1つのパターンだけが一致するとすれば、一致の文字列を取得する必要があります。つまり、入力がabcTWT123の場合、最初に "TST \\ w {1、}"をチェックし、 "TWT \\ w {1、}"に移動し、IDストリングと一致するので "TWT123"に設定されます。 – SuperCow

答えて

1

は結果でマッチした文字列を収集するには、あなたがより少ない一致している場合は、あなたの正規表現でグループを作成する必要があります文字列全体:

List<Pattern> patterns = new ArrayList<>(); 
patterns.add(Pattern.compile("(TST\\w+)"); 
... 

Optional<String> result = Optional.empty(); 
for (Pattern pattern: patterns) { 
    Matcher matcher = pattern.match(); 
    if (matcher.matches()) { 
     result = Optional.of(matcher.group(1)); 
     break; 
    } 
} 

それとも、あなたがストリームに精通している場合:

Optional<String> result = patterns.stream() 
    .map(Pattern::match).filter(Matcher::matches) 
    .map(m -> m.group(1)).findFirst(); 

代わりに、暗黙のうちにグループを作成するfind(@ Raffaeleの回答のように)を使用する方法があります。

もう1つの方法は、すべての一致を1つのパターンにすることです。

Pattern pattern = Pattern.compile("(TST\\w+|TWT\\w+|..."); 

次に、1回の操作で一致してグループ化することができます。しかし、これにより、時間の経過とともにマッチを変更するのが難しくなる可能性があります。

グループ1は最初にマッチしたグループ(最初の括弧内の一致)です。グループ0はマッチ全体です。だから、試合全体(私はあなたの質問からわからなかった)を望むなら、あなたはおそらくグループ0を使うことができます。

+0

私はOPにもグループが必要だと思っていましたが、 'match.find()を使用しているので、 _match.find()_は、_find_または_match_を介在させない場合に_match.group()_が取得する暗黙のグループを作成します。 (まあ、それはパターンの1つだけが一致すると仮定して、そして/またはあなたが一致を見つけるときに停止する) –

+0

良い点。私はそれがOPの意味であることを認識していなかった。私は私の答えを編集します。 – sprinter

1

はたぶん、あなただけのループを終了する必要があります。

// TST\\w{1,} 
// TWT\\w{1,} 
private List<Pattern> patterns; 

public String findIdOrNull(String input) { 
    for (Pattern p : patterns) { 
    Matcher m = p.matcher(input); 
    // First match. If the whole string must match use .matches() 
    if (m.find()) { 
     return m.group(0); 
    } 
    } 
    return null; // Or throw an Exception if this should never happen 
} 
0

交代|(正規表現OR)を使用します

Pattern pattern = Pattern.compile("TST\\w+|TWT\\w+|etc"); 

をその後一度だけのパターンを確認してください。

{1,}+に置き換えることができます。

0

あなたのパターンは、すべての例のような単純な接頭辞TSTあることを行っている場合とTWTあなたはとてもあなたがパターンをループする必要はありません一度にそれらのすべて、およびユーザー正規表現交代|を定義することができます。

例:今すぐ

String prefixes = "TWT|TST|WHW"; 
    String regex = "(" + prefixes + ")\\w+"; 
    Pattern pattern = Pattern.compile(regex); 

    String input = "abcTST123"; 
    Matcher match = pattern.matcher(input); 
    String ID = match.find() ? match.group() : null; 

    // given this, ID will come out as "TST123" 

prefixesは、java .propertiesファイル、または単純なテキストファイルから読み取ることができます。これを行うメソッドにパラメータとして渡されます。
接頭辞をカンマで区切ったリストまたはファイル内の1行に定義して、それを処理してからone|two|three|etcにすることもできます。

複数の入力をループしている可能性があり、regexpatternの変数を1回だけ作成し、別々の入力ごとにMatcherのみを作成したいとします。

関連する問題