【问题标题】:How to match all characters in a string and collect multiple groups?如何匹配字符串中的所有字符并收集多个组?
【发布时间】:2019-07-18 19:34:08
【问题描述】:

我试图弄清楚如何使用 preg_match_all 在特定匹配中选择所有“-on_”。

我尝试了很多正则表达式模式,但我完全被难住了。我们公司最好的正则表达式已经为此工作了一两个小时,也没有取得任何进展。

这似乎是最有前途的.*(-on_).* - 但只捕获每场比赛的最后一个“-on_”。第一个匹配也可以正常工作,但第二个匹配是页面上的所有内容。我不明白为什么。

我正在尝试解析的 HTML 示例...

<span class="RatingStar__bew-avgstars__2enAh">
            <div class="RatingStar__be-c-star__24d1B ">
                <span><span class="RatingStar__be-star-off__2ks1e">★</span></span>
                <span><span class="RatingStar__be-star-on__28Wmg">★</span></span>
            </div>
            <div class="RatingStar__be-c-star__24d1B ">
                <span><span class="RatingStar__be-star-off__2ks1e">★</span></span>
                <span><span class="RatingStar__be-star-on__2ks1e">★</span></span>
            </div>
            <div class="RatingStar__be-c-star__24d1B ">
                <span><span class="RatingStar__be-star-off__2ks1e">★</span></span>
                <span><span class="RatingStar__be-star-on__2ks1e">★</span></span>
            </div>
            <div class="RatingStar__be-c-star__24d1B ">
                <span><span class="RatingStar__be-star-off__2ks1e">★</span></span>
                <span><span class="RatingStar__be-star-on__2ks1e">★</span></span>
            </div>
            <div class="RatingStar__be-c-star__24d1B ">
                <span><span class="RatingStar__be-star-off__2ks1e">★</span></span>
                <span><span class="RatingStar__be-star-off__2ks1e">★</span></span>
            </div>
        </span>

... more unimportant no-need-to-match code between ...


<span class="RatingStar__bew-avgstars__2enAh">
            <div class="RatingStar__be-c-star__24d1B ">
                <span><span class="RatingStar__be-star-off__2ks1e">★</span></span>
                <span><span class="RatingStar__be-star-on__28Wmg">★</span></span>
            </div>
            <div class="RatingStar__be-c-star__24d1B ">
                <span><span class="RatingStar__be-star-off__2ks1e">★</span></span>
                <span><span class="RatingStar__be-star-on__2ks1e">★</span></span>
            </div>
            <div class="RatingStar__be-c-star__24d1B ">
                <span><span class="RatingStar__be-star-off__2ks1e">★</span></span>
                <span><span class="RatingStar__be-star-on__2ks1e">★</span></span>
            </div>
            <div class="RatingStar__be-c-star__24d1B ">
                <span><span class="RatingStar__be-star-off__2ks1e">★</span></span>
                <span><span class="RatingStar__be-star-on__2ks1e">★</span></span>
            </div>
            <div class="RatingStar__be-c-star__24d1B ">
                <span><span class="RatingStar__be-star-off__2ks1e">★</span></span>
                <span><span class="RatingStar__be-star-off__2ks1e">★</span></span>
            </div>
        </span>

我用什么来解析它...

preg_match_all('~<span class="RatingStar__bew-avgstars__2enAh">.*(-on_).*</div></span>~', $html, $matches)

我得到的响应与它有多大并不值得,所以我只是总结一下:

array:2 [▼
  0 => array:2 [▼
    0 => "Perfectly correct match"
    1 => "Match of the rest of the page (not correct)"
  ]
  1 => array:2 [▼
    0 => "-on_" // Last on in the match
    1 => "-on_" // Last on in the second match
  ]
]

对于我应该获得的 2 个匹配项,我应该使用列出的代码获得一组 4 个“-on_”的匹配项。

所以我真正期待的是:

array:2 [▼
  0 => array:2 [▼
    0 => "<span class="RatingStar__bew-avgstars__2enAh"><div class="RatingStar__be-c-star__24d1B "><span><span class="RatingStar__be-star-off__2ks1e">★</span></span><span ▶"
    1 => "<span class="RatingStar__bew-avgstars__2enAh"><div class="RatingStar__be-c-star__24d1B "><span><span class="RatingStar__be-star-off__2ks1e">★</span></span><span ▶"
  ]
  1 => array:2 [▼
    0 => ["-on_","-on_","-on_","-on_"] 
    1 => ["-on_","-on_","-on_","-on_"]
  ]
]

Maybe I'm completely missing something here... any advice?

【问题讨论】:

  • 至少尝试过使用.*?
  • 我很困惑。这是我通过preg_match_all 运行您的sn-p 时得到的:phpliveregex.com/p/sR9#tab-preg-match-all 这与您显示的响应不同。它永远不会“匹配页面的其余部分”。
  • 也许使用 DOMDocument 和 XPath 可能是更好的解决方案,因为它了解您搜索内容的结构和上下文。
  • @WiktorStribiżew 我试过了。*?而且,似乎仍然无法让它工作。
  • (旁白:不要担心单次投反对票。征求反馈意见没有任何价值,除非您希望读者猜出有人投反对票的原因。投票在设计上是匿名的,并且没有义务人们解释他们的投票。)

标签: php regex


【解决方案1】:

我相信这更接近你想要的:

~<span class="RatingStar__bew-avgstars__2enAh">[\s\S]*?(-on_)[\s\S]*?</div>\s*</span>~

你有三个问题:

  1. .* 与换行符 \n 不匹配。 More info。您可以改用 [\s\S]*,它匹配每个空白字符和每个非空白字符(因此,每个字符)。
  2. 文本&lt;/div&gt;&lt;/span&gt; 不会出现在您的sn-p 中。 &lt;/div&gt;&lt;/span&gt; 之间有空格。因此,&lt;/div&gt;\s*?&lt;/span&gt;
  3. 您使用的是贪婪运算符*,而不是惰性运算符*?。这是一个问题,因为您的整个字符串以 &lt;/div&gt;&lt;/span&gt; 结尾,这意味着第一个匹配项将消耗所有其他匹配项并继续到字符串的末尾。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-12-07
    • 1970-01-01
    • 1970-01-01
    • 2021-03-31
    • 2019-06-26
    • 1970-01-01
    • 1970-01-01
    • 2017-11-03
    相关资源
    最近更新 更多