Mam plik z kilkoma niestandardowymi tagami i chciałbym napisać wyrażenie regularne, aby wyodrębnić ciąg między tagami. Na przykład, jeśli mój tag to:
[customtag]String I want to extract[/customtag]
Jak napisać wyrażenie regularne, aby wyodrębnić tylko ciąg między tagami. Ten kod wydaje się krokiem we właściwym kierunku:
Pattern p = Pattern.compile("[customtag](.+?)[/customtag]");
Matcher m = p.matcher("[customtag]String I want to extract[/customtag]");
Nie wiem, co robić dalej. Jakieś pomysły? Dzięki.
[]
nawiasy kwadratowe, które są metaznakami w wyrażeniu regularnym.Odpowiedzi:
Jesteś na dobrej drodze. Teraz wystarczy wyodrębnić żądaną grupę w następujący sposób:
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
Jeśli chcesz wyodrębnić wiele trafień, spróbuj tego:
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; }
Zgadzam się jednak, że wyrażenia regularne nie są tutaj najlepszą odpowiedzią. Użyłbym XPath do znalezienia interesujących mnie elementów. Zobacz API Java XPath po więcej informacji.
źródło
"<tag>apple</tag><b>hello</b><tag>orange</tag><tag>pear"
? Jak możemy siępear
obejść bez tagu?Szczerze mówiąc, wyrażenia regularne nie są najlepszym pomysłem na tego typu analizowanie. Opublikowane przez Ciebie wyrażenie regularne prawdopodobnie będzie dobrze działać w prostych przypadkach, ale jeśli sprawy staną się bardziej złożone, będziesz mieć ogromne problemy (z tego samego powodu, dla którego nie możesz niezawodnie przeanalizować HTML za pomocą wyrażeń regularnych). Wiem, że prawdopodobnie nie chcesz tego słyszeć. Wiem, że tego nie robiłem, gdy zadawałem pytania tego samego typu, ale analizowanie ciągów znaków stało się dla mnie O WIELE bardziej niezawodne, gdy przestałem używać wyrażeń regularnych do wszystkiego.
jTopas to NIESAMOWITY tokenizer, który bardzo ułatwia ręczne pisanie parserów (MOCNIE sugeruję użycie jtopa zamiast standardowych bibliotek skanera java / etc ..). Jeśli chcesz zobaczyć jtopas w akcji, oto kilka parserów, które napisałem przy użyciu jTopas do parsowania tego typu pliku
Jeśli analizujesz pliki XML, powinieneś używać biblioteki parsera xml. Nie rób tego sam, chyba że robisz to tylko dla przyjemności, istnieje wiele sprawdzonych opcji
źródło
Ogólne, prostsze i nieco prymitywne podejście do znajdowania znacznika, atrybutu i wartości
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)); } }
źródło
<h2>Mac</h2><h1>loves it</h1>
lub<h2>Mac<h1>liked your answer</h1></h2>
?Spróbuj tego:
Na przykład:
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()) }
Wynik:
10 Ene
3,08%
źródło
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));
źródło
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++; }
źródło
Przedrostuję tę odpowiedź słowami "nie powinieneś używać wyrażenia regularnego do analizowania XML - spowoduje to tylko przypadki skrajne, które nie działają poprawnie, oraz wyrażenie regex o stale rosnącej złożoności, gdy spróbujesz to naprawić . ”
Biorąc to pod uwagę, musisz kontynuować, dopasowując ciąg i chwytając żądaną grupę:
if (m.matches()) { String result = m.group(1); // do something with result }
źródło