2011-07-03 39 views
59

Tôi có một tệp với một số thẻ tùy chỉnh và tôi muốn viết cụm từ thông dụng để trích xuất chuỗi giữa các thẻ. Ví dụ: nếu thẻ của tôi là:Java regex để trích xuất văn bản giữa các thẻ

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

Làm cách nào để viết biểu thức chính quy để trích xuất chuỗi giữa các thẻ. Mã này có vẻ như một bước đi đúng hướng:

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

Bạn không chắc chắn phải làm gì tiếp theo. Bất kỳ ý tưởng? Cảm ơn.

+1

Để bắt đầu, bạn cần phải thoát khỏi '[]' dấu ngoặc vuông là metacharacters trong một regex. – ridgerunner

Trả lời

127

Bạn đang đi đúng hướng. Bây giờ bạn chỉ cần giải nén các nhóm mong muốn, như sau:

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)); // Prints String I want to extract 

Nếu bạn muốn trích xuất nhiều hit, hãy thử này:

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

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; 
} 

Tuy nhiên, tôi đồng ý rằng biểu thức thông thường không phải là câu trả lời tốt nhất đây. Tôi muốn sử dụng XPath để tìm các yếu tố mà tôi quan tâm. Xem The Java XPath API để biết thêm thông tin.

+3

Cảm ơn rất nhiều, đó chỉ là những gì tôi cần. Tôi sẽ xem xét các XPath, nhưng bây giờ tôi nghĩ giải pháp này sẽ hoạt động. Ứng dụng của tôi rất đơn giản và có thể sẽ vẫn như vậy. Cảm ơn một lần nữa! – b10hazard

+0

Cảm ơn, Nó đã hoạt động !! – Imran

+0

cảm ơn bạn thân mến đã thực sự giúp đỡ –

1

Tôi tiền tố trả lời này với "bạn không nên sử dụng cụm từ thông dụng để phân tích cú pháp XML - nó sẽ dẫn đến các trường hợp cạnh không hoạt động đúng và regex tăng dần trong khi bạn cố gắng sửa nó."

đó đang được nói, bạn cần phải tiến hành bằng cách kết hợp các chuỗi và grabbing nhóm bạn muốn:

if (m.matches()) 
{ 
    String result = m.group(1); 
    // do something with result 
} 
9

Để được khá trung thực, biểu thức thông thường không phải là ý tưởng tốt nhất cho loại phân tích cú pháp. Biểu thức chính quy mà bạn đăng sẽ có thể hoạt động tốt cho các trường hợp đơn giản, nhưng nếu mọi thứ trở nên phức tạp hơn, bạn sẽ gặp phải các vấn đề lớn (cùng một lý do tại sao bạn không thể phân tích cú pháp HTML một cách đáng tin cậy bằng các cụm từ thông dụng). Tôi biết bạn có lẽ không muốn nghe điều này, tôi biết tôi đã không khi tôi hỏi cùng một loại câu hỏi, nhưng phân tích chuỗi trở thành WAY đáng tin cậy hơn cho tôi sau khi tôi ngừng cố gắng sử dụng biểu thức chính quy cho mọi thứ.

jTopas là trình mã thông báo AWESOME giúp dễ dàng viết các trình phân tích cú pháp bằng tay (tôi MẠNH M j gợi ý các jtopas trên thư viện/máy quét java chuẩn). Nếu bạn muốn xem jtopas trong hành động, here là một số phân tích cú pháp tôi đã viết bằng jTopas để phân tích this loại tập tin

Nếu bạn đang phân tích các file XML, bạn nên sử dụng một thư viện xml parser.Đừng làm điều đó bản thân bạn trừ khi bạn đang chỉ làm nó cho vui, có Plently các tùy chọn đã được kiểm chứng trên mạng

+0

Cảm ơn bạn đã đề xuất. Tôi đã đánh dấu chúng và tôi chắc chắn sẽ xem xét việc sử dụng nó trong các dự án trong tương lai. Bây giờ, phương pháp regex có lẽ là phương pháp tôi sẽ sử dụng vì tệp tôi đang phân tích cú pháp rất nhỏ/đơn giản. – b10hazard

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)); 
4

Một chung chung, đơn giản hơn và một cách tiếp cận chút nguyên thủy để tìm thẻ, thuộc tính và giá trị so

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)); 
     } 
    } 
2

Hãy thử điều này:

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

Ví dụ:

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())  
} 

Output:

10 Ene

3,08%

0
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++; 
     } 
Các vấn đề liên quan