我知道正则表达式不适合这项任务。但我无法使用解析器,因为我需要保留 OFFSET 。所以我在这里有两个问题,一个是关于正则表达式,另一个是提取“作者”。如果您建议我使用任何解析器,请告诉我是否有解析器可以保留偏移量。 我有这样的xml:
<post author="lafeat" datetime="2014-04-03T04:26:00" id="p1">
For legions of young couples, there is no wedding venue more desirable than a barn in the country.
</post>
我的代码在这里:
String regex = "<post\\s*?author=\"(?!\")*\"?.*?>.*?</post>";
Pattern p = Pattern.compile(regex);
Matcher m = p.matcher(text);
while (m.find()) {
System.out.println("start from: " + m.start());
System.out.println("end to: " + m.end());
System.out.println("the text is: " + text.substring(m.start(), m.end()));
}
但我从这个正则表达式中得不到任何回报? 任何建议都会非常感谢。
答案 0 :(得分:2)
使用专用的HTML解析器比你能想出的任何正则表达式更好。
回答你的问题:
此处不需要否定前瞻。它无论如何都被错误地使用了:
您无法对零宽度断言应用量词,即您无法执行此操作:(?!\")*
。这是因为前面的标记,零宽度负向前瞻表达式,不可量化。
你没有遍历字符串。由于您的正则表达式当前已写入,因此它仅检查单个位置。值得注意的是,环绕声断言是零宽度 - 它与任何字符都不匹配。因此,为了将第一个双引号中的所有字符都捕获到下一个引号,您必须实际匹配文本。您可以使用点来实现此目的:(?:(?!\").)*
。它将逐个字符地逐个字符前进,直到它到达一个双引号的位置。
这是你应该如何编写表达式(see demo):
<post\\s*?author=\"((?:(?!\").)*).*?>
但它不需要那么复杂。你可以使用一个否定的字符类并完成它(see demo):
<post\\s*?author=\"([^\"]+)\".*?>
\"([^\"]+)\"
是一个否定的字符类,它匹配除双引号之外的任何字符,一次或多次。
答案 1 :(得分:2)
您没有得到任何回报,因为您错误地使用了否定前瞻并且没有捕获组。如果要提取作者,请使用捕获组。
String regex = "<post\\s*author=\"([^\"]+)\"[^>]+>[^><]+</post>";
然后在此处返回匹配的组:
while (m.find()) {
System.out.println("start from: " + m.start());
System.out.println("end to: " + m.end());
System.out.println("the text is: " + m.group(1));
}