正则表达式重复的类

时间:2011-11-29 00:48:58

标签: php regex

我试图找出以下的正则表达式:

<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匹配

4 个答案:

答案 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*表示会有一个以BC开头的字符串,然后可能会跟踪一些空格。

答案 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>个元素。更容易。