无法匹配从网页读取的多行HTML代码

时间:2013-06-13 22:18:50

标签: java html regex

这是HTML代码:

         <td class="foobar" id="12345POE46" data="more &amp; data">
               <a href="http://www.stackoverflow.com" more="{data}">Value</a>                    </td>

现在,我不是正则表达式的新手,但我是Java的正则表达式的新手。我唯一想知道的是如何在Java中使用这个正则表达式,这是我用来从代码中提取值的那个:

(?s)<td class="foobar".*?<a.*?>(.*?)</a>.*?</td>

我需要(?s),因为<td><a>之间有换行符。

根据我的研究,我在Java中需要做的就是将DOTALL参数传递给模式编译函数:

p = Pattern.compile(regex, Pattern.DOTALL);

然后这个正则表达式应该起作用:

<td class="foobar".*?<a.*?>(.*?)</a>.*?</td>

因为DOTALL参数应该像(?s)标志一样。

但它不起作用。我搜索了一会儿,却找不出那是什么问题。


这是我阅读HTML代码的方式:

URL web = new URL(webURL); 
URLConnection gate = web.openConnection(); 
BufferedReader in = new BufferedReader(new InputStreamReader(gate.getInputStream()));
String inputLine = in.readLine();

更新:

  • 我用我的正则表达式测试了相同的代码,它在我尝试过的所有在线正则表达式测试器中都很有效(带有(?s)标志)。

  • 我在Python中编写了所有代码,一切都相同,并且当我从网页HTML I索引到Java时,它与(?s)标志完美匹配。

    < / LI>

2 个答案:

答案 0 :(得分:1)

使用(?s)的原始版本应该可以正常工作,因为Java supports match flags。如果指定内联标记,则不需要DOTALL。

更新:如果您的模式不匹配,则出于其他原因。这段代码:

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class MatchFlags {
    public static void main(String[] args) {
        String s = "foo\nbar";
        System.out.println(s.matches("foo.bar"));
        System.out.println(s.matches("(?s)foo.bar"));
        Matcher m = Pattern.compile("foo.bar", Pattern.DOTALL).matcher(s);
        System.out.println(m.matches());
    }
}

生成此输出:

false
true
true

如您所见,(?s)内联标记或DOTALL标记将导致通配符与换行匹配。

此外,如果您向其添加终止</td>,则您提供的示例可以正常工作:

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class MatchFlags {
    public static void main(String[] args) {
        String in =
            "<td class=\"foobar\" id=\"12345POE46\" data=\"more &amp; data\">\n" +
            "    <a href=\"http://www.stackoverflow.com\" more=\"{data}\">Value</a>\n" +
            "</td>";
        Matcher matcher = Pattern
                .compile("(?s)<td class=\"foobar\".*?<a.*?>(.*?)</a>.*?</td>")
                .matcher(in);
        System.out.println(matcher.find());
        System.out.println(matcher.group(1));
    }
}

产生

true
Value

答案 1 :(得分:0)

您的正则表达式似乎对我很好,我使用以下代码进行测试:

String s = "  <td class=\"foobar\">\n"
         + "\n"
         + "        <a href=\"http://www.webaddress.com\">Value</a>        </td>\n";
String regex = "<td class=\"foobar\".*?<a.*?>(.*?)</a>.*?</td>";
Pattern p = Pattern.compile(regex, Pattern.DOTALL);
Matcher m = p.matcher(s);
if (m.find()) {
    System.out.println("Found a match!\n");
}

示例:http://ideone.com/geoLlA