정규 표현식을 사용하여 Java를 사용하여 더 큰 문자열의 하위 문자열 찾기


140

다음과 같은 문자열이 있으면

FOO[BAR]

문자열에서 "BAR"문자열을 가져 오는 일반적인 방법이 필요하므로 대괄호 사이에 어떤 문자열이 있더라도 문자열을 얻을 수 있습니다.

예 :

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

답변:


253

욕심없는 정량자를 사용할 수 있어야합니다 (특히 *?). 아마도 다음을 원할 것입니다.

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

이렇게하면 문자열과 일치하는 패턴을 제공하고 첫 번째 그룹의 대괄호 안에 텍스트를 넣습니다. 자세한 내용 은 Pattern API 설명서 를 참조하십시오.

문자열을 추출하려면 다음과 같은 것을 사용할 수 있습니다.

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

16
대괄호 사이에 줄 바꿈이 있으면 이것이 실패하고이를 피하기 위해 Pattern.DOTALL 플래그를 사용해야합니다.
cletus

위의 패턴을 사용하여 문자열 BAR을 포함하는 문자열을 추출하는 데 어떻게 사용합니까? Pattern API와 Matcher API를보고 있지만 여전히 문자열 자체를 얻는 방법을 잘 모르겠습니다.
digiarnie

@cletus : 좋은 전화! @ digiarnie : 나는 일치를 얻기위한 짚맨 코드가 포함 된 답변을 수정에 추가했습니다.
Bryan Kyle

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
하위 문자열 등의 색인 또는 정규 표현식이 더 빠릅니다.
Toskan

2
아래의 "추출 된"에 대한 Amit의 값을 참조하십시오 : 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[123하고 FOO.
정규식으로 변경하면 \[(.*)\]괜찮지 만 다음과 같이 더 복잡한 것에서 내용을 추출하려고하면 다음과 같습니다.

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

어떤 정규식도 작동하지 않습니다.

모든 경우에 적합한 컨텐츠를 추출하는 가장 정확한 Regex는 []쌍 을 균형을 잡고 컨텐츠를 제공 해야하기 때문에 훨씬 더 복잡 합니다.

더 간단한 솔루션

문제가 복잡해지고 []임의 의 내용이 복잡해지면 대신 []정규식보다 오래된 오래된 코드 선반을 사용하여 쌍의 균형을 잡고 문자열을 추출 할 수 있습니다 .

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가 일정하다고 가정합니다.

그래서 이것을 자바로 넣으려면 :

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("]"));

첫 번째 '['와 마지막 ']'사이의 값을 반환합니다.

푸 [바] => 바

푸 [바 [테스트]] => 바 [테스트]

참고 : 입력 문자열이 제대로 구성되지 않은 경우 오류 검사를 추가해야합니다.


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.