正则表达式进阶:正向后行断言

5
这是我的测试字符串:

<img rel="{objectid:498,newobject:1,fileid:338}" width="80" height="60" align="left" src="../../../../files/jpg1/Desert1.jpg" alt="" />

我希望能获取rel属性之间的每个JSON元素。目前已成功获取第一个元素(objectid)。

以下是我的正则表达式,它可以正常工作:

(?<=(rel="\{objectid:))\d+(?=[,|\}])

但我想做类似于这样的事情,但它不能工作:

(?<=(rel="\{.*objectid:))\d+(?=[,|\}])

所以我可以解析搜索字符串中的每个元素。

我正在使用Java-ReqEx。

3个回答

2

Java(以及除.NET和JGSoft之外的几乎所有正则表达式)不支持在后顾结构中使用无限重复。

你可以使用捕获组代替。此外,最好使用[^{]*而不是.*,并使用\b确保单词边界。

rel="\{[^{]*\bobjectid:(\d+)

应该足够了(然后查看捕获组1以获取属性的值)。

1
你想要遍历所有的键/值对吗?这并不需要回顾。
String s = 
    "<img rel=\"{objectid:498,newobject:1,fileid:338}\" " +
    "width=\"80\" height=\"60\" align=\"left\" " +
    "src=\"../../../../files/jpg1/Desert1.jpg\" alt=\"\" />";
Pattern p = Pattern.compile(
    "(?:\\brel=\"\\{|\\G,)(\\w+):(\\w+)");
Matcher m = p.matcher(s);
while (m.find())
{
  System.out.printf("%s = %s%n", m.group(1), m.group(2));
}

第一次调用find()时,正则表达式的第一部分匹配rel="{。在随后的调用中,第二个备选项(\G,)接管以匹配逗号,但仅当它紧随前一个匹配时才会匹配。无论哪种情况,它都会让您对齐(\w+):(\w+)以匹配下一个键/值对,并且它永远不会匹配rel属性之外的任何地方。

我假设您将正则表达式应用于孤立的IMG标记,就像您发布的那样,而不是整个HTML文件。此外,正则表达式可能需要进行一些微调才能匹配您的实际数据。例如,您可能希望使用更通用的([^:]+):([^,}]+)而不是(\w+):(\w+)


0

一般情况下,前瞻和后顾不能包含任意正则表达式:大多数引擎(包括Java)要求其长度是已知的,因此您不能在其中使用诸如*之类的量词。

无论如何,为什么要在这里使用前瞻和后顾呢?只需使用捕获组即可,这样更简单。

rel="\{.*objectid:(\d+)

现在第一个捕获组将包含ID。


不是真的。在前瞻中无限重复没有问题,只有在后顾中才会出现问题。 - Tim Pietzcker

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接