我试图找出以下的正则表达式:
<tr class="A">.*</tr><tr class="(B|C)">.*</tr>
现在第二个tr类将重复未知次数,重复之间有一些未知的东西,但只是将它放在括号中并添加一个加号不起作用。
这是不起作用的PHP代码:
$pattern = '/<tr\ class=\"A\">.*(<tr\ class=\"(B|C)\">.*<\/tr>.*)+/';
preg_match_all($pattern,$playerHtml,$scores);
但它只返回第一个
这是一个应该匹配的例子:
<tr class="A">blah</tr>blah
<tr class="B">blah</tr>blah
<tr class="B">blah</tr>blah
<tr class="C">blah</tr>
这只与blahblahblah匹配
答案 0 :(得分:1)
对于您的特定示例,此正则表达式将执行:
/<tr class="A">.*?<\/tr>.*\n?(<tr class="[BC]">.*?<\/tr>.*\n?)+/
希望你能在必要时调整它。请参阅键盘演示here。
我需要添加\n
换行符才能正常工作。
因为它们是TABLE元素之外的TR元素,所以我很难看到preg_match_all函数的结果(因为我的浏览器立即剥离了随机TR元素)。您可能遇到过类似的问题。我在演示中使用了htmlspecialchars()来输出正则表达式匹配。
,在两个TR元素之间使用文本是不合适的:
<tr></tr>blah<tr></tr>
所以你应该小心这样做。
答案 1 :(得分:0)
尝试:
<tr class="A">.*</tr><tr class="((B|C)\s*)+">.*</tr>
+
表示一次或多次,*
表示0次或更多次。此外\s
也会提供空格。
((B|C)\s*)+
表示会有一个或多个(B|C)\s*
(B|C)\s*
表示会有一个以B
或C
开头的字符串,然后可能会跟踪一些空格。
答案 2 :(得分:0)
我无法测试,因为我在手机上,但你用这种模式得到的分数是多少?
<tr class="A">.*</tr><tr class="((B)|(C)|[^"]+)+">.*</tr>
答案 3 :(得分:0)
preg_match_all
会多次查找您的整个模式。
因为它只发现一次(我假设因为开始只在$playerHtml
一次),所以你只得到一次匹配。
相反,首先查找整个模式并提取您感兴趣的部分,然后继续该部分:
$pattern = '/<tr\ class=\"A\">.*(<tr\ class=\"(B|C)\">.*<\/tr>.*)+/';
$r = preg_match($pattern, $playerHtml, $matches);
if (FALSE === $r) throw new Exception('Regex failed.');
list(,$scoreHtml) = $matches;
$r = preg_match_all('/(<tr\ class=\"(B|C)\">.*<\/tr>.*)/', $scoreHtml, $scores);
if (FALSE === $r) throw new Exception('Regex failed.');
这段代码写得很快,肯定不会起作用,只是为了说明你需要做多个步骤。
但是,如果您使用的是HTML解析器而不是正则表达式,我敢打赌,使用一些小的xpath查询获取您所使用的值会更加快捷:
//tr[@class="B" or @class="C"]
这会选择您查找的所有<tr>
个元素。更容易。