正規表現を使用してJavaでより大きな文字列の部分文字列を検索する


140

このような文字列がある場合:

FOO[BAR]

文字列から「BAR」文字列を取得する一般的な方法が必要です。角括弧の間にある文字列に関係なく、文字列を取得できます。

例えば

FOO[DOG] = DOG
FOO[CAT] = CAT

回答:


253

貪欲でない量指定子、具体的には*?を使用できるはずです。あなたはおそらく以下を望んでいるでしょう:

Pattern MY_PATTERN = Pattern.compile("\\[(.*?)\\]");

これにより、文字列に一致するパターンが得られ、最初のグループの角括弧内にテキストが配置されます。詳細については、パターンAPIドキュメントをご覧ください。

文字列を抽出するには、次のようなものを使用できます。

Matcher m = MY_PATTERN.matcher("FOO[BAR]");
while (m.find()) {
    String s = m.group(1);
    // s now contains "BAR"
}

16
角括弧の間に改行がある場合、これは失敗するので、Pattern.DOTALLフラグを使用してそれを回避する必要があることに言及する価値があります。
cletus 2009年

上記のパターンを使用して、それをどのように使用して、文字列BARを含む文字列を抽出しますか?パターンAPIとマッチャーAPIを調べていますが、文字列自体を取得する方法がわかりません。
digiarnie 2009年

@cletus:いいね!@digiarnie:マッチを取得するためのストローマンコードが含まれている回答にリビジョンを追加しました。
ブライアンカイル

30

非正規表現の方法:

String input = "FOO[BAR]", extracted;
extracted = input.substring(input.indexOf("["),input.indexOf("]"));

または、パフォーマンス/メモリ使用量をわずかに向上させる(Hosamに感謝):

String input = "FOO[BAR]", extracted;
extracted = input.substring(input.indexOf('['),input.lastIndexOf(']'));

1
lastIndexOf(']')代わりに、ネストされたブラケットを処理するのに使用します。さらに、を使用するindexOf(char)方がよりも高速になると思いますindexOf(String)
Hosam Aly

どういたしまして。パフォーマンスに関するメモも非常に関連性がありlastIndexOfます。これは、閉じ括弧を見つけるのが確実に速くなるためです。
Hosam Aly

3
indexofサブストリングなど、または正規表現は何が速いですか?
Toskan、2011

2
以下の「抽出」のアミットの値を参照してください:input.indexOf( '[')+ 1
gcbound

28

これは実際の例です:

RegexpExample.java

package org.regexp.replace;

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class RegexpExample
{
    public static void main(String[] args)
    {
        String string = "var1[value1], var2[value2], var3[value3]";
        Pattern pattern = Pattern.compile("(\\[)(.*?)(\\])");
        Matcher matcher = pattern.matcher(string);

        List<String> listMatches = new ArrayList<String>();

        while(matcher.find())
        {
            listMatches.add(matcher.group(2));
        }

        for(String s : listMatches)
        {
            System.out.println(s);
        }
    }
}

それは表示します:

value1
value2
value3

6
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public static String get_match(String s, String p) {
    // returns first match of p in s for first group in regular expression 
    Matcher m = Pattern.compile(p).matcher(s);
    return m.find() ? m.group(1) : "";
}

get_match("FOO[BAR]", "\\[(.*?)\\]")  // returns "BAR"

public static List<String> get_matches(String s, String p) {
    // returns all matches of p in s for first group in regular expression 
    List<String> matches = new ArrayList<String>();
    Matcher m = Pattern.compile(p).matcher(s);
    while(m.find()) {
        matches.add(m.group(1));
    }
    return matches;
}

get_matches("FOO[BAR] FOO[CAT]", "\\[(.*?)\\]")) // returns [BAR, CAT]

5

[]にあるものを何でも取得する必要がある場合は、次の\[([^\]]*)\]ように使用できます。

Pattern regex = Pattern.compile("\\[([^\\]]*)\\]");
Matcher m = regex.matcher(str);
if (m.find()) {
    result = m.group();
}

フォームidentifier + [ + content + ]にする必要がある場合は、識別子が英数字の場合にのみコンテンツの抽出を制限できます。

[a-zA-Z][a-z-A-Z0-9_]*\s*\[([^\]]*)\]

これによりFoo [Bar]、またはなどが検証さmyDevice_123["input"]れます。

主な問題

主な問題は、次のような内容を抽出する場合です。

FOO[BAR[CAT[123]]+DOG[FOO]]

正規表現は機能せず、復帰BAR[CAT[123FOOます。
正規表現をに変更\[(.*)\]すれば問題ありませんが、次のようなより複雑なものからコンテンツを抽出しようとしている場合は、次のようになります。

FOO[BAR[CAT[123]]+DOG[FOO]] = myOtherFoo[BAR[5]]

正規表現はどれも機能しません。

すべてのケースで適切なコンテンツを抽出する最も正確な正規表現は、[]ペアのバランスを取り、コンテンツを提供する必要があるため、はるかに複雑になります。

よりシンプルなソリューション

問題が複雑になり、[]任意の内容が含まれている場合は、代わりに、[]正規表現よりも単純な古いコードレイトを使用して、ペアのバランスを取り、文字列を抽出できます。

int i;
int brackets = 0;
string c;
result = "";
for (i = input.indexOf("["); i < str.length; i++) {
    c = str.substring(i, i + 1);
    if (c == '[') {
        brackets++;
    } else if (c == ']') {
        brackets--;
        if (brackets <= 0) 
            break;
    }
    result = result + c;
}   

これは実際のコードよりも疑似コードであり、Javaコーダーではないため、構文が正しいかどうかはわかりませんが、改善するのは簡単です。
重要なのは、このコードが機能して、のコンテンツを抽出できる[]ことです。ただし、複雑であってもかまいません。


2

正規表現は次のようになります。

/FOO\[(.+)\]/

FOOが一定になると仮定します。

したがって、これをJavaに配置するには:

Pattern p = Pattern.compile("FOO\\[(.+)\\]");
Matcher m = p.matcher(inputLine);

FOO [BAR] FOO [BAZ]->次の正規表現が返されます: "BAR] FOO [BAZ"
Mohammad Jafar Mashhadi

1
String input = "FOO[BAR]";
String result = input.substring(input.indexOf("[")+1,input.lastIndexOf("]"));

これは最初の '['と最後の ']'の間の値を返します

Foo [バー] =>バー

Foo [バー[テスト]] =>バー[テスト]

注:入力文字列の形式が適切でない場合は、エラーチェックを追加する必要があります。


0

/ FOO \ [([^ \]] *)\] /内で他の右角括弧が許可されていないと仮定


0

私は間以外]の最大文字数たいことを定義したい[とし]。これらはバックスラッシュでエスケープする必要があり(Javaではこれらを再度エスケープする必要があります)、non-]の定義は文字クラスであるため、内部[および](つまり[^\\]])です。結果:

FOO\\[([^\\]]+)\\]

0

このように、mYearInDB.toString()= [2013]からの文字列を解析したい場合は、2013になります。

Matcher n = MY_PATTERN.matcher("FOO[BAR]"+mYearInDB.toString());
while (n.find()) {
 extracredYear  = n.group(1);
 // s now contains "BAR"
    }
    System.out.println("Extrated output is : "+extracredYear);

0

この正規表現は私にとってはうまくいきます:

form\[([^']*?)\]

例:

form[company_details][0][name]
form[company_details][0][common_names][1][title]

出力:

Match 1
1.  company_details
Match 2
1.  company_details

http://rubular.com/でテスト済み


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.