1

次の結果を提供する正しい正規表現を探しています。

  • 一重/二重引用符で囲まれた単語をグループ化する必要があります
  • 文字列に他の一重引用符がない場合、一重引用符を出力し続ける必要があります
  • 一重/二重引用符で囲まれていない場合 - スペースで分割

私は現在持っています:

Pattern pattern = Pattern.compile("[^\\s\"']+|\"([^\"]*)\"|'([^']*)'");

...しかし、次の例は完全には機能していません。誰がこれを手伝ってくれますか?

例:

  • フーバー
    • group1: フー
    • group2: バー
    • 説明: スペースで分割
  • 「フーバー」
    • group1: フーバー
    • 説明: 二重引用符で囲んで foo と bar をグループ化しますが、二重引用符を出力しないでください
  • 「フーバー」
    • group1: フーバー
    • 説明: 上記と同じですが、一重引用符が付きます
  • 'フーバー
    • group1: 'ふー
    • group2: バー
    • 説明: スペースで分割し、一重引用符を保持
  • 「フーバー」
    • group1: 'フーバー
    • 説明: 二重引用符で囲み、'foo と bar をグループ化し、単一引用符のままにする
  • フーバー」
    • group1: フー
    • group2: バー'
  • フーバー」
    • group1: フー
    • group2: バー"
  • 「フーバー」「スタックオーバーフロー」
    • group1: フーバー
    • group2: スタック オーバーフロー
  • 「foo' バー」「スタック オーバーフロー」お元気ですか
    • group1: フーバー
    • group2: スタック オーバーフロー
    • group3: どうやって
    • group4: する
    • group5: あなた
    • group6: する
4

2 に答える 2

7

これを 1 回の呼び出しで実行できるかどうかはわかりませんがMatcher.match、ループで実行できます。このコードは、繰り返し
使用することで、上記のすべてのケースを解決します。Matcher.find()

Pattern pattern = Pattern.compile("\"([^\"]+)\"|'([^']+)'|\\S+");
List<String> testStrings = Arrays.asList("foo bar", "\"foo bar\"","'foo bar'", "'foo bar", "\"'foo bar\"", "foo bar'", "foo bar\"", "\"foo bar\" \"stack overflow\"", "\"foo' bar\" \"stack overflow\" how do you do");
for (String testString : testStrings) {
    int count = 1;
    Matcher matcher = pattern.matcher(testString);
    System.out.format("* %s%n", testString);
    while (matcher.find()) {
        System.out.format("\t* group%d: %s%n", count++, matcher.group(1) == null ? matcher.group(2) == null ? matcher.group() : matcher.group(2) : matcher.group(1));
    }
}

これは以下を出力します:

* foo bar
    * group1: foo
    * group2: bar
* "foo bar"
    * group1: foo bar
* 'foo bar'
    * group1: foo bar
* 'foo bar
    * group1: 'foo
    * group2: bar
* "'foo bar"
    * group1: 'foo bar
* foo bar'
    * group1: foo
    * group2: bar'
* foo bar"
    * group1: foo
    * group2: bar"
* "foo bar" "stack overflow"
    * group1: foo bar
    * group2: stack overflow
* "foo' bar" "stack overflow" how do you do
    * group1: foo' bar
    * group2: stack overflow
    * group3: how
    * group4: do
    * group5: you
    * group6: do
于 2012-10-05T08:51:25.383 に答える
1

ペアリング (引用符または中括弧) がある場合はいつでも、正規表現の領域を離れて、パーサーを必要とする文法の領域に入ります。

この質問に対する究極の答えをあなたに残します

アップデート:

もう少し説明。

通常、文法は次のように表されます。

construct -> [set of constructs or terminals]

たとえば、引用の場合

doblequotedstring := " simplequotedstring "
simplequotedstring := string ' string
                      | string '
                      | ' string
                      | '

これは簡単な例です。インターネットで引用するための文法の適切な例があります。

これにはaflexとajaccを使用しました(Adaの場合、Javaにはjflexとjjaccが存在します)。識別子のリストを aflex に渡し、出力を生成し、その出力と文法を ajacc に渡すと、Ada パーサーが得られます。それらを使用してからかなりの時間が経過しているため、より合理化されたソリューションがあるかどうかはわかりませんが、基本的には同じ入力が必要になります.

于 2012-10-05T08:20:29.950 に答える