当文本之间存在空格和回车符时,我在执行正则表达式时遇到困难。
例如下面这个例子,如何让正则表达式得到“
<div id="contentleft">
”?
<div id="content">
<div id="contentleft"> <SCRIPT language=JavaScript>
我试过了
id="content">(.*?)<SCRIPT
但是不起作用。
$s = '<div id="content">
<div id="contentleft"> <SCRIPT language=JavaScript>';
if( preg_match('/id="content">(.*?)<SCRIPT/s', $s, $matches) )
print $matches[1]."\n";
默认情况下,点匹配除换行符之外的所有内容。
/s
使它匹配一切。
但实际上,请使用 DOM 解析器。 您可以遍历树,也可以使用 XPath 查询。 将其想象为 XML 的正则表达式。
$s = '<div id="content">
<div id="contentleft"> <SCRIPT language=JavaScript>';
// Load the HTML
$doc = new DOMDocument();
$doc->loadHTML($s);
// Use XPath to find the <div id="content"> tag's descendants.
$xpath = new DOMXPath($doc);
$entries = $xpath->query("//div[@id='content']/descendant::*");
foreach( $nodes as $node ) {
// Stop when we see <script ...>
if( $node->nodeName == "script" )
break;
// do what you want with the content
}
XPath 非常强大。 这里有一些例子。
PS 我确信(我希望)上面的代码可以收紧一些。
查看 PCRE 修饰符:https://www.php.net/manual/en/reference.pcre.pattern.modifiers.php
您可以应用 s 修饰符,例如
'/id="content">(.*?)<SCRIPT/s'
(不过,请注意,因为它也会改变 ^
和 $
的工作方式。
否则,你可以这样做
'/id="content">((.|\n)*?)<SCRIPT/'
编辑:哎呀,修饰符错误...
尝试
id="content">((?:.|\n)*?)<SCRIPT
不要使用正则表达式解析 HTML 的常见警告适用,但您似乎已经知道了。
或者:
(?<=id="content">)(?:.|\n)*?(?=<SCRIPT)
默认情况下,点不匹配换行符。解决这个问题的一种方法是明确允许它们。即使您碰巧使用的正则表达式风格不支持“dotall”修饰符,这也会起作用。
第一个正则表达式与您的方法相同,通过允许
\n
进行扩展。您的比赛将属于第 1 组,您只需修剪它即可。
第二个正则表达式使用零宽度断言(向前看/向后看)来标记匹配的开始和结束。比赛不会包含任何您不想要的内容,无需分组。
另一种没有正则表达式的解决方案:
$start = 'id="content">';
$end = '<SCRIPT';
if (($startPos = strpos($str, $start)) !== false &&
($endPos = strpos($str, $end, $startPos+1)) !== false) {
$substr = substr($str, $startPos, $endPost-$startPos);
}
嗯,这是一个多行问题,所以看看模式修饰符:
m (PCRE_MULTILINE) 默认情况下,PCRE 将主题字符串视为 由一条“线”组成 字符(即使实际上 包含几个换行符)。开始 of line" 元字符 (^) 匹配 仅在字符串的开头,而 “行尾”元字符 ($) 仅在字符串末尾匹配, 或在终止换行符之前 (除非设置了 D 修饰符)。这是 与 Perl 相同。
设置此修饰符后,“开始 of line” 和 “end of line” 结构 紧接着或之后匹配 紧接在任何换行符之前 主题字符串也分别 就像一开始和结束时一样。这是 相当于 Perl 的 /m 修饰符。如果 没有“ ” 中的字符 主题字符串,或没有出现 ^ 或模式中的$,设置此 修改器没有效果。
s (PCRE_DOTALL) 如果此修饰符是 集,一个点元字符 模式匹配所有字符, 包括换行符。没有它, 换行符被排除。这个修饰符 相当于 Perl 的 /s 修饰符。 A 负类如 [^a] 总是 匹配换行符, 与此设置无关 修饰符。
来自 http://www.php.net/manual/en/reference.pcre.pattern.modifiers.php
$dom = new DOMDocument();
$dom->strictErrorChecking = false;
$dom->loadHTML($html_str);
$xpath = new DOMXPath($dom);
$div = $xpath->query('div[@id="content"]')->item(0);
请更正我的 xpath 表达式 - 不确定它是否有效...