6

特定の部分文字列を含む文から各単語を抽出する関数を作成しようとしています。たとえば、「Porky Pork Chop」で「Po」を検索すると、Porky Pork が返されます。

regexpal で正規表現をテストしましたが、Java コードが機能していないようです。私は何を間違っていますか?

private static String foo()
    {

        String searchTerm = "Pizza";
        String text = "Cheese Pizza";

        String sPattern =  "(?i)\b("+searchTerm+"(.+?)?)\b";
        Pattern pattern = Pattern.compile ( sPattern );
        Matcher matcher = pattern.matcher ( text );
        if(matcher.find ())
        {
            String result = "-";
            for(int i=0;i < matcher.groupCount ();i++)
            {
                result+= matcher.group ( i ) + " ";
            }
            return result.trim ();
        }else
        {
            System.out.println("No  Luck");
        }
    }
4

6 に答える 6

3
  1. Java で\b 単語境界を正規表現エンジンに渡すには、\\b. \bString オブジェクトのバックスペースを表します。

  2. あなたの例から判断すると、部分文字列を含むすべての単語を返す必要があります。これを行うには使用しませんfor(int i=0;i < matcher.groupCount ();i++)while(matcher.find())、グループ数はすべての一致ではなく、単一の一致ですべてのグループを反復するためです。

  3. 文字列にいくつかの特殊文字を含めることができる場合は、おそらく使用する必要がありますPattern.quote(searchTerm)

  4. コードで検索しようとしているので、検索"Pizza""Cheese Pizza"れた部分文字列と同じ文字列も検索したいと思います。正規表現は正常に機能しますが、最後の部分(.+?)?)をに変更し、単語の途中で部分文字列も一致させる必要がある場合は、開始時\\w*に追加することもできます (開始時だけでなく)。\\w*

したがって、コードは次のようになります

private static String foo() {

    String searchTerm = "Pizza";
    String text = "Cheese Pizza, Other Pizzas";

    String sPattern = "(?i)\\b\\w*" + Pattern.quote(searchTerm) + "\\w*\\b";
    StringBuilder result = new StringBuilder("-").append(searchTerm).append(": ");

    Pattern pattern = Pattern.compile(sPattern);
    Matcher matcher = pattern.matcher(text);
    while (matcher.find()) {
        result.append(matcher.group()).append(' ');
    }
    return result.toString().trim();
}
于 2013-07-27T20:54:56.673 に答える
2

正規表現のアプローチは確かに有効な方法ですが、単語を空白で分割すると、より簡単に考えることができます。Stringこれは、のsplitメソッドで実行できます。

public List<String> doIt(final String inputString, final String term) {
    final List<String> output = new ArrayList<String>();
    final String[] parts = input.split("\\s+");
    for(final String part : parts) {
        if(part.indexOf(term) > 0) {
            output.add(part);
        }
    }
    return output;
}

もちろん、これを行うと、入力文字列を介して 2 つのパスが効果的に実行されることには何の価値もありません。分割する空白である文字を見つけるための最初のパスと、部分文字列の各分割単語を調べるための 2 番目のパス。

ただし、1 つのパスが必要な場合は、正規表現パスの方が適しています。

于 2013-07-27T20:56:52.537 に答える
1

nicholas.hauschildの答えが最高だと思います。

ただし、本当に正規表現を使用したい場合は、次のようにすることができます。

String searchTerm = "Pizza";
String text = "Cheese Pizza";
Pattern pattern = Pattern.compile("\\b" + Pattern.quote(searchTerm)
        + "\\b", Pattern.CASE_INSENSITIVE);
Matcher matcher = pattern.matcher(text);
while (matcher.find()) {
    System.out.println(matcher.group());
}

出力:

Pizza
于 2013-07-27T21:01:24.570 に答える
1

パターンは

String sPattern =  "(?i)\\b("+searchTerm+"(?:.+?)?)\\b";

(ピザ) 文字列全体をキャプチャする必要があります。?:文字列の一部を 2 回キャプチャしないようにします。

于 2013-07-27T21:02:32.513 に答える
0

わかりました、生のスタイルでパターンを提供します(Javaスタイルではなく、自分でダブルエスケープする必要があります):

(?i)\b[a-z]*po[a-z]*\b



それだけです。

于 2013-07-27T21:20:08.857 に答える
0

このパターンを試してください:

String searchTerm = "Po";
String text = "Porky Pork Chop oPod zzz llPo";

Pattern p = Pattern.compile("\\p{Alpha}+" + substring + "|\\p{Alpha}+" + substring + "\\p{Alpha}+|" + substring + "\\p{Alpha}+");

Matcher m = p.matcher(myString);

while(m.find()) {
    System.out.println(">> " + m.group());
}
于 2013-07-27T21:03:53.300 に答える