태그 사이의 텍스트를 추출하는 Java 정규식


82

사용자 지정 태그가있는 파일이 있고 태그 사이의 문자열을 추출하는 정규식을 작성하고 싶습니다. 예를 들어 내 태그가 다음과 같은 경우

[customtag]String I want to extract[/customtag]

태그 사이의 문자열 만 추출하는 정규식을 어떻게 작성합니까? 이 코드는 올바른 방향으로 나아가는 단계처럼 보입니다.

Pattern p = Pattern.compile("[customtag](.+?)[/customtag]");
Matcher m = p.matcher("[customtag]String I want to extract[/customtag]");

다음에 무엇을해야할지 모르겠습니다. 어떤 아이디어? 감사.


1
우선, []정규식에서 메타 문자 인 대괄호 를 이스케이프해야합니다 .
ridgerunner

답변:


184

당신은 올바른 길을 가고 있습니다. 이제 다음과 같이 원하는 그룹을 추출하기 만하면됩니다.

final Pattern pattern = Pattern.compile("<tag>(.+?)</tag>", Pattern.DOTALL);
final Matcher matcher = pattern.matcher("<tag>String I want to extract</tag>");
matcher.find();
System.out.println(matcher.group(1)); // Prints String I want to extract

여러 히트를 추출하려면 다음을 시도하십시오.

public static void main(String[] args) {
    final String str = "<tag>apple</tag><b>hello</b><tag>orange</tag><tag>pear</tag>";
    System.out.println(Arrays.toString(getTagValues(str).toArray())); // Prints [apple, orange, pear]
}

private static final Pattern TAG_REGEX = Pattern.compile("<tag>(.+?)</tag>", Pattern.DOTALL);

private static List<String> getTagValues(final String str) {
    final List<String> tagValues = new ArrayList<String>();
    final Matcher matcher = TAG_REGEX.matcher(str);
    while (matcher.find()) {
        tagValues.add(matcher.group(1));
    }
    return tagValues;
}

그러나 정규 표현식이 여기에서 최선의 답이 아니라는 데 동의합니다. 관심있는 요소를 찾기 위해 XPath를 사용하겠습니다. 자세한 내용 은 Java XPath API 를 참조하십시오.


3
정말 감사합니다. 그게 제가 필요한 것입니다. XPath를 살펴 보 겠지만 지금은이 솔루션이 작동 할 것이라고 생각합니다. 내 응용 프로그램은 매우 간단하며 아마 그대로 유지 될 것입니다. 다시 한 번 감사드립니다!
b10hazard 2011

이 문자열은 "<tag>apple</tag><b>hello</b><tag>orange</tag><tag>pear"어떻습니까? pear닫기 태그없이 어떻게 얻을 수 있습니까?
K.Sopheak

일반화하려면 : private String extractDataFromTags (String tag) {Pattern pattern = Pattern.compile ( "<. +?> (. +?) </.+?>"); 매처 매처 = pattern.matcher (tag); matcher.find (); 반환 (matcher.group (1)); // 추출하고자하는 문자열을 출력하거나 예외를 발생
시킵니다

15

솔직히 말해서 정규 표현식은 이러한 유형의 구문 분석에 가장 적합한 아이디어가 아닙니다. 게시 한 정규식은 간단한 경우에는 잘 작동하지만 상황이 더 복잡해지면 큰 문제가 발생할 것입니다 (정규식으로 HTML을 안정적으로 구문 분석 할 수없는 동일한 이유). 나는 당신이 아마 이것을 듣고 싶지 않다는 것을 알고 있습니다. 같은 유형의 질문을 할 때 나는 그렇지 않았지만 모든 것에 정규 표현식을 사용하려는 시도를 중단 한 후에 문자열 구문 분석이 더 안정적이되었습니다.

jTopas 는 손으로 파서를 작성하는 것을 매우 쉽게 만들어주는 멋진 토크 나이저입니다 (저는 표준 자바 스캐너 / 기타. jtopas가 작동하는 모습을보고 싶다면 여기 에 jTopas를 사용하여이 유형의 파일 을 구문 분석 하기 위해 작성한 구문 분석기 가 있습니다.

XML 파일을 구문 분석하는 경우 xml 파서 라이브러리를 사용해야합니다. 재미로하는 것이 아니라면 스스로하지 마십시오. 검증 된 옵션이 많이 있습니다.


제안 해 주셔서 감사합니다. 나는 그것들을 북마크에 추가했고 향후 프로젝트에서 이것을 사용하는 것을 확실히 조사 할 것입니다. 지금은 정규식 방법이 아마도 내가 파싱하는 파일이 매우 작거나 간단하기 때문에 함께 갈 것입니다.
b10hazard 2011

7

태그, 속성 및 값을 찾기위한 일반적이고 단순하며 약간 원시적 인 접근 방식

    Pattern pattern = Pattern.compile("<(\\w+)( +.+)*>((.*))</\\1>");
    System.out.println(pattern.matcher("<asd> TEST</asd>").find());
    System.out.println(pattern.matcher("<asd TEST</asd>").find());
    System.out.println(pattern.matcher("<asd attr='3'> TEST</asd>").find());
    System.out.println(pattern.matcher("<asd> <x>TEST<x>asd>").find());
    System.out.println("-------");
    Matcher matcher = pattern.matcher("<as x> TEST</as>");
    if (matcher.find()) {
        for (int i = 0; i <= matcher.groupCount(); i++) {
            System.out.println(i + ":" + matcher.group(i));
        }
    }

같은 다른 태그 또는 중첩 된 태그의 순서가있는 경우 패턴 어떤 것 <h2>Mac</h2><h1>loves it</h1>또는 <h2>Mac<h1>liked your answer</h1></h2>?
MAC

1
편집하십시오 i <matcher.groupCount (); 나는 <= matcher.groupCount (); 첫 번째 일치하는 부분 문자열을 포함합니다. 0th index
AVA

4

이 시도:

Pattern p = Pattern.compile(?<=\\<(any_tag)\\>)(\\s*.*\\s*)(?=\\<\\/(any_tag)\\>);
Matcher m = p.matcher(anyString);

예를 들면 :

String str = "<TR> <TD>1Q Ene</TD> <TD>3.08%</TD> </TR>";
Pattern p = Pattern.compile("(?<=\\<TD\\>)(\\s*.*\\s*)(?=\\<\\/TD\\>)");
Matcher m = p.matcher(str);
while(m.find()){
   Log.e("Regex"," Regex result: " + m.group())       
}

산출:

10 적

3.08 %


2
    final Pattern pattern = Pattern.compile("tag\\](.+?)\\[/tag");
    final Matcher matcher = pattern.matcher("[tag]String I want to extract[/tag]");
    matcher.find();
    System.out.println(matcher.group(1));

태그의 접두어는
어떻습니까

2
    String s = "<B><G>Test</G></B><C>Test1</C>";

    String pattern ="\\<(.+)\\>([^\\<\\>]+)\\<\\/\\1\\>";

       int count = 0;

        Pattern p = Pattern.compile(pattern);
        Matcher m =  p.matcher(s);
        while(m.find())
        {
            System.out.println(m.group(2));
            count++;
        }

1

이 답장에 "XML을 구문 분석하는 데 정규식을 사용해서는 안됩니다. 문제를 해결하려고 시도하는 동안 제대로 작동하지 않는 엣지 케이스와 계속해서 복잡성이 증가하는 정규식이 나타날뿐입니다. . "

즉, 문자열을 일치시키고 원하는 그룹을 잡아 계속 진행해야합니다.

if (m.matches())
{
   String result = m.group(1);
   // do something with result
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.