通过PHP的preg_match()匹配多行模式

35

如何使用PHP preg_match()正则表达式模式匹配此HTML代码中的subject

      <table border=0>
  <tr>
  <td>


  <h2>subject</h2>



    </td>

所有的空格和换行符都是有意留下的。因此,问题在于使用某个多行模式提取主题名称。


本文可能对 使用 preg_match 在 PHP 中进行多行搜索 有用。 - Ali Yousefi
6个回答

67
如果你正在寻找嵌套在 td 标签中的 h2 标签,两者之间只有空格,并且需要包含空格、换行符等,请使用 \s。例如:
preg_match('#<td>\s*<h2>(.*?)</h2>\s*</td>#i',$str,$matches);
// result is in $matches[1]

在此处可以看到它的效果:这里

为您提供这里不同修饰符列表,您可以传递给preg_*函数。可能会有用的标志包括:

  • s ("dotall"):使得.匹配每个字符,包括换行符。因此,如果您的<h2>.....</h2>跨越多行,则需要执行下面的操作:

    preg_match('#<td>\s*<h2>(.*?)</h2>\s*</td>#is',$str,$matches);
    

    为了让.*可以跨越多行(请看正则表达式末尾的额外s?)。

  • m("multiline"):这个选项只是允许^$匹配每行的开头和结尾,而不仅仅是整个字符串的开头和结尾。如果您在模式中使用^$并希望它们与输入中每个单独行的开头和结尾匹配,则只有在需要时才需要它。

3
谢谢!在找到您的帖子之前,我卡了1.5小时。我需要的是"s"属性。 - codemonkey613
我想匹配多行输入中特定行的开头,因此使用'/^start/im' - Derek Illchuk

15

您可以在正则表达式中添加m运算符:

// Given your HTML content.
$html = 'Your HTML content';
preg_match('/<td[^>]*>(.*?)<\/td>/im', $html, $matches);

希望这 (仍然) 有所帮助,哈哈哈。


8
我认为你正在思考的是s修饰符(用于“DOTALL”或“单行”模式),这已经被建议过了。建议链接:https://dev59.com/Rmox5IYBdhLWcg3wzXel#8959000。 - Alan Moore
7
这个“哈哈哈”非常令人不安。 - Ch3shire
2
如果需要,尝试添加"sU"以及"m" - E Ciotti

4

1
我一直在寻找这个答案。我很惊讶,五年后竟然没有人建议使用正则表达式解析HTML可能是一个不好的主意。不明白为什么会被踩。 - s3v3n
是的,欢迎加入我们。尽管如此,我仍然坚持我的答案 :) - Maciej Paprocki
1
这绝对是处理这个问题的正确方式。至少给它又点了一个赞 :-) - Marty
4
我还没有对此进行投票,但是我可能要补充一点,即它忽略了问题的重点,即如何在多行文本中使用preg_match。如果您不喜欢这个用例,那么它并没有回答问题。 - Manngo
嗯,我认为我提供了比现有方案更好的解决方案。如果有人使用错误的工具,难道不应该告诉他们并提供更好的替代方案吗? - Maciej Paprocki

3
非常简单,使用:
preg_match('/<h2>(.*?)<\\/h2>/', $str, $matches);
print($matches[1]);

多行格式对正则表达式没有影响,除非你需要匹配跨越多行的字符串。


抱歉,我应该更具体地说明问题。我处理的HTML代码中缺少“标识符”。可能会有其他h2标签和其他标签。因此,我正在尝试使用周围的标签来精确地定位代码中的特定位置。那么,如何使正则表达式模式理解多行?... - Dmitriy Ryabinin

0

使用4个反引号(作为Markdown语法)来捕获一个代码块。

例子易于适应。

<?php

$str = '
# Some Text

```` 
    h5 {
      font-size: 1rem;
      font-weight: 600;
    }
````

And some text.
';

$reg = '/````[^>]*(.*?)````/';

preg_match($reg, $str, $matches);
echo $matches[0];

/* OUTPUT
```` 
    h5 {
      font-size: 1rem;
      font-weight: 600;
    }
````
*/

echo preg_replace($reg, "DELETED", $str);

/* OUTPUT
# Some Text

DELETED

And some text.
*/

你正在回答什么问题? - Toto
通过PHP的preg_match()匹配多行模式 - NVRM

-5
你必须使用正则表达式中的 \s 来删除所有换行符:
$str ="<ol>
         <li>Capable for unlimited product</li>
         <li>Two currency support</li>
         <li>Works with touch screens and click screen based systems</li>
         <li>Responsive design <b>shopping cart</b>, Specially design for Mac, iPhone, iPad, PC and Android</li>
         <li>VAT for countries that support a Value Added Tax</li>
         <li>Barcode scanner checkout option for POS</li>
         <li>mRSS</li>
       </ol>";

preg_match("/^([A-Za-z0-9\s\<\>\.\,\/\-\ ]+)$/", $str);

// Sanitize your code before save to database.

function test_input($data) {
    $data = trim($data);
    $data = htmlspecialchars($data);
    $data = json_encode($data);
    $data = addslashes($data);
    return $data;
}

echo test_input($str);

我认为他想保留换行 - Maciej Paprocki

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