这是我的模式(Live example):
(?:"|")id(?:"|"):(?:"|")(.{0,200}?)(?:"|").{0,200}?(?:"|")urn:li:fs_miniCompany:65514(?:"|")
如您所见,它将后续字符串与第一个捕获组匹配:
/p/3/005/07a/356/1399435.png","$type":"com.linkedin.voyager.common.MediaProcessorImage","$id":
但这是预期的结果:
/p/3/005/07a/356/1399435.png
我该怎么做?
注意:我可以使用[^&]+
停止匹配,但在这种情况下,会引发Catastrophic Backtracking
错误。
答案 0 :(得分:0)
您可以使用负向前瞻来匹配除一系列字符之外的所有内容。我还建议不要使用{0,200}
因为它似乎是随机的。此模式与第一个PNG路径匹配。如果你想拥有最后一个,我会使用更具体的选择器,而不是使用{0,200}
:
(?:"|")id(?:"|"):(?:"|")(.*?)(?:"|").*?(?!").*?(?:"|")urn:li:fs_miniCompany:65514(?:"|")
答案 1 :(得分:0)
拥有结构化数据时,请勿使用字符串方法。您实际上正在搜索html <code>
标记内的JSON字符串中的内容。
使用XPath提取包含子串"urn:li:fs_miniCompany:65514"
的{{1}}标记文本是一项简单的任务,可以大大减少搜索范围。
然后您需要做的就是进行少量更改以获取JSON字符串(修剪不需要的字符并用双引号替换"e;
实体)
$dom = new DOMDocument;
libxml_use_internal_errors(true);
$dom->loadHTMLFile('yourfile.html'); // or $dom->loadHTML($yourstring);
$xp = new DOMXPath($dom);
$codeContent = $xp->evaluate('string(//code[contains(., "urn:li:fs_miniCompany:65514")])');
$json = str_replace('"e;', '"', trim($codeContent, "\r\n \t\\n"));
$arr = json_decode($json, true);
print_r(array_column($arr['included'], 'id'));
你只需要找到如何根据json结构选择你想要的那个(使用print_r($arr)
来可视化它)。
关于您的模式的一般注意事项:
(?:"e;|")
的理由,因为每个引号似乎都被其html实体替换。"e;
应该足够了。) 当没有其他方法时:
/pattern/S
/(?=[&"])(?:"e;|").../
或者这样:/[&"](?:(?<=&)quote;|(?<=")).../
a.*b.*c
(如a.*?b.*?c
或a.{1,n}b.{1,n}c
或a.{1,n}?b.{1,n}?c
)是众所周知的灾难性回溯来源。这种模式允许主题字符串中的单个位置组合太多,并且在失败之前需要很多步骤和时间,因为每个组合都经过测试。