我正在使用Pattern和Matcher创建一个regexp,它将从我在下面的li标签中提取6个值:
<ul class="Bold"> <li class="ball-orange">2</li> <li class="ball-orange">10</li> <li class="ball-orange">11</li> <li class="ball-orange">15</li> <li class="ball-orange">22</li> <li class="ball-orange">39</li> </ul>
即。正则表达式的结果需要是2,10,11,15,22,39的组。
我有以下代码:
Pattern numbersPattern = Pattern.compile(".*(<li class=\"ball-orange\">([0-9]{1,2})</li>).*");
Matcher matchNumbers = numbersPattern.matcher(mainBlock);//mainBlock is the string I quoted above which contains all the li's
System.out.println("Numbers Match? " + matchNumbers.matches());//this returns true
System.out.println(matchNumbers.group(2));//returns 39, i.e. second group but for the last li
//this loop never gets entered!!!
while (matchNumbers.find()) {
System.out.println("group 1: " + matcher.group(1));
System.out.println("group 2: " + matcher.group(2));
//System.out.println("group 3: " + matcher.group(3));
}
因此,您可以从评论中看到匹配最后一个li,但它不会进入while(matchNumbers.find())循环。即我希望找到(<li class=\"ball-orange\">([0-9]{1,2})</li>)
6次,并在循环中输出,但不是。
我跟随这里的啧啧 - http://tutorials.jenkov.com/java-regex/matcher.html#groups-inside-groups。
为什么没有输入循环,怎样才能让li的组匹配?
答案 0 :(得分:2)
您的正则表达式.*(<li class=\"ball-orange\">([0-9]{1,2})</li>).*
将占用整个字符串,因为.*
在开头和结尾。如果您想进入循环,请考虑仅使用(<li class=\"ball-orange\">([0-9]{1,2})</li>)
部分。
甚至更好,而不是正则表达式使用适当的工具:HTML解析器,如jsoup:
String mainBlock = "<ul class=\"Bold\"> <li class=\"ball-orange\">2</li> <li class=\"ball-orange\">10</li> <li class=\"ball-orange\">11</li> <li class=\"ball-orange\">15</li> <li class=\"ball-orange\">22</li> <li class=\"ball-orange\">39</li> </ul>";
Document doc = Jsoup.parse(mainBlock);
for (Element el : doc.select("li.ball-orange")){//pick all <li class="ball-orange"> tags
System.out.println("li tag: " + el);
System.out.println("value in li : " + el.text());
}
输出:
li tag: <li class="ball-orange">2</li>
value in li : 2
li tag: <li class="ball-orange">10</li>
value in li : 10
li tag: <li class="ball-orange">11</li>
value in li : 11
li tag: <li class="ball-orange">15</li>
value in li : 15
li tag: <li class="ball-orange">22</li>
value in li : 22
li tag: <li class="ball-orange">39</li>
value in li : 39
答案 1 :(得分:1)
目前,您热切地匹配整个字符串(任何内容+ li +任何内容),这就是matches() == true
的原因。如果你想要所有,只需删除.*
部分,因为.find()
会多次找到你的模式,首先是位置~25,然后是〜60等等......:
String mainBlock = "<ul class=\"Bold\"> <li class=\"ball-orange\">2</li> <li class=\"ball-orange\">10</li> <li class=\"ball-orange\">11</li> <li class=\"ball-orange\">15</li> <li class=\"ball-orange\">22</li> <li class=\"ball-orange\">39</li> </ul>";
Pattern listPattern = Pattern.compile("<li class=\"ball-orange\">([0-9]{1,2})</li>");
Matcher matcher = listPattern.matcher(mainBlock);
while (matcher.find()) {
System.out.println("whole thing: " + matcher.group()); // or group(0)
System.out.println("number: " + matcher.group(1));
}
整件事:&lt; li class =&#34; ball-orange&#34;&gt; 2&lt; / li&gt;
编号:2
整件事:&lt; li class =&#34; ball-orange&#34;&gt; 10&lt; / li&gt;
数量:10
整件事:&lt; li class =&#34; ball-orange&#34;&gt; 11&lt; / li&gt;
数量:11
整件事:&lt; li class =&#34; ball-orange&#34;&gt; 15&lt; / li&gt;
数量:15
整件事:&lt; li class =&#34; ball-orange&#34;&gt; 22&lt; / li&gt;
数量:22
整件事:&lt; li class =&#34; ball-orange&#34;&gt; 39&lt; / li&gt;
数量:39
注意:你永远不需要在整个正则表达式中放置一个组,根据定义捕获组0是整个匹配,这就是为什么编号从1开始。
答案 2 :(得分:-1)
您必须将正则表达式更改为"\<li class=\"ball-orange\"\>\d{1,2}\</li\>"
使用\ d而不是[0-9]
Pattern numbersPattern = Pattern.compile("\<li class=\"ball-orange\"\>\d{1,2}\</li\>");
Matcher matchNumbers = numbersPattern.matcher(mainBlock);//mainBlock is the string I quoted above which contains all the li's
System.out.println("Numbers Match? " + matchNumbers.matches());//this returns true
System.out.println(matchNumbers.group(2));//returns 39, i.e. second group but for the last li
//this loop never gets entered!!!
while (matchNumbers.find()) {
System.out.println("group 1: " + matcher.group(1));
System.out.println("group 2: " + matcher.group(2));
//System.out.println("group 3: " + matcher.group(3));
}