1

この正規表現は、文を 3 つのトークンに分割するのに正しいですか?

  1. 括弧内の小文字の前の文字
  2. 括弧を含む括弧内の小文字
  3. 小文字の括弧文字の後の文字

System.out.println("This is (a) test".matches("^(.*)?\\([a-z]*\\)(.*)?$"));

文字列には、括弧付きの小文字がある場合とない場合があり、文のどこにでも表示される場合があります。私が考慮していないユースケースに欠陥がある場合は、正規表現で修正を提供できますか?

上記の例の場合。

Group1 captures This is 
Group2 captures (a)
Group3 captures  test

編集::次のことを達成するために正規表現を変更するにはどうすればよいですか?

文字列に (foo)(bar)(baz) が含まれている場合、group1= empty group2=(foo) および group3=empty をキャプチャするにはどうすればよいですか。かっこが 3 つあるので、上記のパターンを 3 回見つけます。

4

5 に答える 5

0

最初と 3 番目のグループに括弧の前後のすべての文字を含める場合は、 and除外する必要があり(ます)( 2 番目の例.*のように、括弧を含むグループにも一致(foo)(bar)します)。

だから私はこれに置き換え.*ます[^\\(\\)]*

また、2 番目のグループの多くの部分文字列を含む文字列と一致させたい場合 (2 番目の例のように)、*2 番目のグループの後にある必要があります。

私の結果はこれでした:

^([^\\(\\)]*)?(\\([a-z]*\\))*([^\\(\\)]*)?$

これは最初の例と 2 番目の例で機能しますが、2 番目のグループは最終的に最後に見つかったもののみを保存します - (bz).

2 番目の例で述べたように、2 番目のグループを 3 回キャプチャできるようにしたい場合は、while m.find()代わりにif m.matches()( mis a Matcherobject);を使用してみてください。また、正規表現をこれに少し変更します。

([^\\(\\)]*)(\\([a-z]*\\))([^\\(\\)]*)

これは、文字列内のすべての可能な一致の 2 番目のグループになります - (foo), (bar), (bz).

編集:私が本当に説明できない何らかの理由で、私にとっては(foo)、他の2つだけが見つかりません。find()そこで、最後に見つかったグループが終了した位置から明示的に開始して、パラメーターを適用しようとするコードを書きました。

String regex = "([^\\(\\)]*)(\\([a-z]*\\))([^\\(\\)]*)";
String text = "(foo)(bar)(bz)";
Pattern p = Pattern.compile(regex);
Matcher m = p.matcher(text);

for (int reg = 0; reg < text.length(); reg+=(m.end()-m.start()))
        if (m.find(reg))
            for (int group = 1; group <=m.groupCount(); group++)
                System.out.println("Group "+group+": "+m.group(group));

これは機能し、出力は次のとおりです。

Group 1: 
Group 2: (foo)
Group 3: 
Group 1: 
Group 2: (bar)
Group 3: 
Group 1: 
Group 2: (bz)
Group 3: 
于 2013-05-14T21:21:30.747 に答える
0

正規表現を調べることとは別に、正規表現を作成するときは常に、各ケースをカバーする一連の単体テストを作成します。同じことをすることをお勧めします。正規表現と文字列に対するテストを使用して、(少なくとも) 4 つのテストを作成します。

  • (a) これはテストです
  • これはテストです
  • これはテストです(a)
  • これはテストです

これは、説明した各ケースをカバーする必要があります。これは、ケースごとに正規表現を手動で分析しようとするよりもはるかに簡単で高速です。

于 2013-05-14T17:08:28.773 に答える
0

下括弧内の文字を確実にしたい場合は、 を使用する必要があります+

[a-z]+

このままでThis is (a) (b) testは譲れない

Group1 captures This is 
Group2 captures (a)
Group3 captures  (b) test

Group2 が期待される(b)場合は、Group1 で貪欲な正規表現を使用する必要があります。

推奨されるテスト ケース:

  • 空 - 本当に空です。箇条書きを空にすることはできません。
  • フー(バー)バズ
  • (フー)(バー)(バズ)
  • (フー)バー(バズ)
  • フー(バー)(バズ)ビング
  • フー(バー)バズ(ビング)
  • フー(バー)
  • (フー)バー
于 2013-05-14T17:09:07.157 に答える
0

パイソンでは:

r=re.compile(r'([^()]*)(\([a-z)(]*\))([^()]*)')

r.match('abc(xx)dd').groups()
  ('abc', '(xx)', 'dd')`
r.match('abc(xx)(dd)dd').groups()
  ('abc', '(xx)(dd)', 'dd')
r.match('(abc)').groups()
  ('', '(abc)', '')
于 2013-05-14T21:49:02.973 に答える
0

あなたの正規表現には少し問題があります。

定義では、実際にはパターンに 2 が含まれているのに、3 つのグループがあると言っています。

リテラル括弧の使用はグループとしてカウントされないため、次のようなものを使用する必要があります。

"^(.*)?(\\([a-z]*\\))(.*)?$"

または、括弧が不要で文字のみが必要な場合は、順序を変更できます。

"^(.*)?\\(([a-z]*)\\)(.*)?$"

それ以外は問題ないようですが、括弧内の小文字はパターンでは必須ではないことに注意してください。

于 2013-05-14T17:13:48.680 に答える