PHP preg_replace() 不起作用
PHP preg_replace() wont work
我正在尝试 运行 这里的脚本。
我确实将一些内容放入变量$x
。
$x
满是 html 代码。
现在我想替换/删除所有 html 评论并将其写入文件。
我有这个正则表达式:<!--([\s\S]*?)-->
。
它在编辑器或 www.phpliveregex.com 中运行良好。
但在我的 php 中没有。
也许你能帮帮我。
//$x = content
$summary2 = preg_replace("<!--([\s\S]*?)-->", "", $x);
fwrite($fh, $summary2);
编辑:
这是我要删除的内容的一些示例。
</ul>
<p>
Evaluation<!--[if gte mso 9]><xml>
<o:OfficeDocumentSettings>
<o:AllowPNG />
<o:TargetScreenSize>1024x768</o:TargetScreenSize>
</o:OfficeDocumentSettings>
</xml><![endif]--><!--[if gte mso 9]><xml>
<w:WordDocument>
<w:View>Normal</w:View>
<w:Zoom>0</w:Zoom>
<w:HyphenationZone>21</w:HyphenationZone>
<w:PunctuationKerning />
<w:ValidateAgainstSchemas />
<w:SaveIfXMLInvalid>false</w:SaveIfXMLInvalid>
<w:IgnoreMixedContent>false</w:IgnoreMixedContent>
<w:AlwaysShowPlaceholderText>false</w:AlwaysShowPlaceholderText>
<w:Compatibility>
<w:BreakWrappedTables />
<w:SnapToGridInCell />
<w:WrapTextWithPunct />
<w:UseAsianBreakRules />
<w:DontGrowAutofit />
</w:Compatibility>
</w:WordDocument>
</xml><![endif]--><!--[if gte mso 9]><xml>
<w:LatentStyles DefLockedState="false" LatentStyleCount="156">
</w:LatentStyles>
</xml><![endif]--><!--[if gte mso 10]>
<style>
/* Style Definitions */
table.MsoNormalTable
{mso-style-name:"Normale Tabelle";
mso-tstyle-rowband-size:0;
mso-tstyle-colband-size:0;
mso-style-noshow:yes;
mso-style-parent:"";
mso-padding-alt:0cm 5.4pt 0cm 5.4pt;
mso-para-margin:0cm;
mso-para-margin-bottom:.0001pt;
mso-pagination:widow-orphan;
font-size:10.0pt;
font-family:"Times New Roman";
mso-ansi-language:#0400;
mso-fareast-language:#0400;
mso-bidi-language:#0400;}
</style>
<![endif]--></p>
<ul>
<li>
由于您使用 < 和 > 作为分隔符,您应该对它们进行转义以将它们从字符串中删除:
$summary2 = preg_replace("<\<!--([\s\S]*?)--\>>", "", $x);
首先,您忘记添加分隔符了。
通常,当您没有分隔符时会发出警告,因为它被视为正则表达式语法错误。
但是在您的特定情况下,不会生成警告,因为您可以使用 < 和 > 作为分隔符。您也可以使用 { }。
由于您的 < 和 > 被用作分隔符,您的正则表达式显然不再符合您的期望。
通常,不带分隔符的正则表达式在测试站点中有效,因为分隔符是自动管理的,无需处理。这当然解释了为什么您的正则表达式在您正在测试它的站点上按原样工作。
其次,我建议将 [\s\S]*?
替换为 .*?
并使用 s 选项。更容易理解您要匹配的内容。
什么是正则表达式?
A sequence of symbols and characters expressing a string or pattern to
be searched for within a longer piece of text.
什么是定界符?
When using the PCRE functions, it is required that the pattern is
enclosed by delimiters. A delimiter can be any non-alphanumeric,
non-backslash, non-whitespace character.
哪一对字符可以用作分隔符?
Often used delimiters are forward slashes (/), hash signs (#) and tildes (~).
It is also possible to use bracket style delimiters where the opening and closing brackets are the starting and ending delimiter, respectively. (), {}, [] and <> are all valid bracket style delimiter pairs.
我的情况呢<!--([\s\S]*?)-->
?
因此,顺便说一下,您的 RegEx 有分隔符,其中以 <
和结束 >
个字符,相应地,您的 RegEx 模式将是 !--([\s\S]*?)--
,这可能不是您想要的。
我该怎么办?
用一对定界符包裹它。例如。 /<!--([\s\S]*?)-->/
有效吗?
这是一个好习惯吗?
不,不是!从不(但为了不撒谎,我有时会这样做!)! Regular Expressions are not made to modify HTML/XML elements。为了这个特定的目的,你应该选择 DOMDocument
class,这将使你的生活更加轻松和清洁:
$dom = new DOMDocument();
$dom->loadHtml($str, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
$xpath = new DOMXPath($dom);
foreach ($xpath->query('//comment()') as $comment) {
$comment->parentNode->removeChild($comment);
}
echo $dom->saveHTML();
在 PHP 中,您需要 return 来自 preg_replace()
的字符串,它不适用于原始字符串。所以这完美地工作(see a demo here as well,在下半部分)。正如评论中提到的,您还需要添加一些分隔符(在我的例子中 ~
):
<?php
$string = '</ul>
<p>
Evaluation<!--[if gte mso 9]><xml>
<o:OfficeDocumentSettings>
<o:AllowPNG />
<o:TargetScreenSize>1024x768</o:TargetScreenSize>
</o:OfficeDocumentSettings>
</xml><![endif]--><!--[if gte mso 9]><xml>
<w:WordDocument>
<w:View>Normal</w:View>
<w:Zoom>0</w:Zoom>
<w:HyphenationZone>21</w:HyphenationZone>
<w:PunctuationKerning />
<w:ValidateAgainstSchemas />
<w:SaveIfXMLInvalid>false</w:SaveIfXMLInvalid>
<w:IgnoreMixedContent>false</w:IgnoreMixedContent>
<w:AlwaysShowPlaceholderText>false</w:AlwaysShowPlaceholderText>
<w:Compatibility>
<w:BreakWrappedTables />
<w:SnapToGridInCell />
<w:WrapTextWithPunct />
<w:UseAsianBreakRules />
<w:DontGrowAutofit />
</w:Compatibility>
</w:WordDocument>
</xml><![endif]--><!--[if gte mso 9]><xml>
<w:LatentStyles DefLockedState="false" LatentStyleCount="156">
</w:LatentStyles>
</xml><![endif]--><!--[if gte mso 10]>
<style>
/* Style Definitions */
table.MsoNormalTable
{mso-style-name:"Normale Tabelle";
mso-tstyle-rowband-size:0;
mso-tstyle-colband-size:0;
mso-style-noshow:yes;
mso-style-parent:"";
mso-padding-alt:0cm 5.4pt 0cm 5.4pt;
mso-para-margin:0cm;
mso-para-margin-bottom:.0001pt;
mso-pagination:widow-orphan;
font-size:10.0pt;
font-family:"Times New Roman";
mso-ansi-language:#0400;
mso-fareast-language:#0400;
mso-bidi-language:#0400;}
</style>
<![endif]--></p>
<ul>
<li>';
$regex = '~<!--([\s\S]*?)-->~';
$replacement = '';
$newString = preg_replace($regex, $replacement, $string);
echo $newString;
?>
我正在尝试 运行 这里的脚本。
我确实将一些内容放入变量$x
。
$x
满是 html 代码。
现在我想替换/删除所有 html 评论并将其写入文件。
我有这个正则表达式:<!--([\s\S]*?)-->
。
它在编辑器或 www.phpliveregex.com 中运行良好。
但在我的 php 中没有。
也许你能帮帮我。
//$x = content
$summary2 = preg_replace("<!--([\s\S]*?)-->", "", $x);
fwrite($fh, $summary2);
编辑: 这是我要删除的内容的一些示例。
</ul>
<p>
Evaluation<!--[if gte mso 9]><xml>
<o:OfficeDocumentSettings>
<o:AllowPNG />
<o:TargetScreenSize>1024x768</o:TargetScreenSize>
</o:OfficeDocumentSettings>
</xml><![endif]--><!--[if gte mso 9]><xml>
<w:WordDocument>
<w:View>Normal</w:View>
<w:Zoom>0</w:Zoom>
<w:HyphenationZone>21</w:HyphenationZone>
<w:PunctuationKerning />
<w:ValidateAgainstSchemas />
<w:SaveIfXMLInvalid>false</w:SaveIfXMLInvalid>
<w:IgnoreMixedContent>false</w:IgnoreMixedContent>
<w:AlwaysShowPlaceholderText>false</w:AlwaysShowPlaceholderText>
<w:Compatibility>
<w:BreakWrappedTables />
<w:SnapToGridInCell />
<w:WrapTextWithPunct />
<w:UseAsianBreakRules />
<w:DontGrowAutofit />
</w:Compatibility>
</w:WordDocument>
</xml><![endif]--><!--[if gte mso 9]><xml>
<w:LatentStyles DefLockedState="false" LatentStyleCount="156">
</w:LatentStyles>
</xml><![endif]--><!--[if gte mso 10]>
<style>
/* Style Definitions */
table.MsoNormalTable
{mso-style-name:"Normale Tabelle";
mso-tstyle-rowband-size:0;
mso-tstyle-colband-size:0;
mso-style-noshow:yes;
mso-style-parent:"";
mso-padding-alt:0cm 5.4pt 0cm 5.4pt;
mso-para-margin:0cm;
mso-para-margin-bottom:.0001pt;
mso-pagination:widow-orphan;
font-size:10.0pt;
font-family:"Times New Roman";
mso-ansi-language:#0400;
mso-fareast-language:#0400;
mso-bidi-language:#0400;}
</style>
<![endif]--></p>
<ul>
<li>
由于您使用 < 和 > 作为分隔符,您应该对它们进行转义以将它们从字符串中删除:
$summary2 = preg_replace("<\<!--([\s\S]*?)--\>>", "", $x);
首先,您忘记添加分隔符了。
通常,当您没有分隔符时会发出警告,因为它被视为正则表达式语法错误。 但是在您的特定情况下,不会生成警告,因为您可以使用 < 和 > 作为分隔符。您也可以使用 { }。 由于您的 < 和 > 被用作分隔符,您的正则表达式显然不再符合您的期望。
通常,不带分隔符的正则表达式在测试站点中有效,因为分隔符是自动管理的,无需处理。这当然解释了为什么您的正则表达式在您正在测试它的站点上按原样工作。
其次,我建议将 [\s\S]*?
替换为 .*?
并使用 s 选项。更容易理解您要匹配的内容。
什么是正则表达式?
A sequence of symbols and characters expressing a string or pattern to be searched for within a longer piece of text.
什么是定界符?
When using the PCRE functions, it is required that the pattern is enclosed by delimiters. A delimiter can be any non-alphanumeric, non-backslash, non-whitespace character.
哪一对字符可以用作分隔符?
Often used delimiters are forward slashes (/), hash signs (#) and tildes (~).
It is also possible to use bracket style delimiters where the opening and closing brackets are the starting and ending delimiter, respectively. (), {}, [] and <> are all valid bracket style delimiter pairs.
我的情况呢<!--([\s\S]*?)-->
?
因此,顺便说一下,您的 RegEx 有分隔符,其中以 <
和结束 >
个字符,相应地,您的 RegEx 模式将是 !--([\s\S]*?)--
,这可能不是您想要的。
我该怎么办?
用一对定界符包裹它。例如。 /<!--([\s\S]*?)-->/
有效吗?
这是一个好习惯吗?
不,不是!从不(但为了不撒谎,我有时会这样做!)! Regular Expressions are not made to modify HTML/XML elements。为了这个特定的目的,你应该选择 DOMDocument
class,这将使你的生活更加轻松和清洁:
$dom = new DOMDocument();
$dom->loadHtml($str, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
$xpath = new DOMXPath($dom);
foreach ($xpath->query('//comment()') as $comment) {
$comment->parentNode->removeChild($comment);
}
echo $dom->saveHTML();
在 PHP 中,您需要 return 来自 preg_replace()
的字符串,它不适用于原始字符串。所以这完美地工作(see a demo here as well,在下半部分)。正如评论中提到的,您还需要添加一些分隔符(在我的例子中 ~
):
<?php
$string = '</ul>
<p>
Evaluation<!--[if gte mso 9]><xml>
<o:OfficeDocumentSettings>
<o:AllowPNG />
<o:TargetScreenSize>1024x768</o:TargetScreenSize>
</o:OfficeDocumentSettings>
</xml><![endif]--><!--[if gte mso 9]><xml>
<w:WordDocument>
<w:View>Normal</w:View>
<w:Zoom>0</w:Zoom>
<w:HyphenationZone>21</w:HyphenationZone>
<w:PunctuationKerning />
<w:ValidateAgainstSchemas />
<w:SaveIfXMLInvalid>false</w:SaveIfXMLInvalid>
<w:IgnoreMixedContent>false</w:IgnoreMixedContent>
<w:AlwaysShowPlaceholderText>false</w:AlwaysShowPlaceholderText>
<w:Compatibility>
<w:BreakWrappedTables />
<w:SnapToGridInCell />
<w:WrapTextWithPunct />
<w:UseAsianBreakRules />
<w:DontGrowAutofit />
</w:Compatibility>
</w:WordDocument>
</xml><![endif]--><!--[if gte mso 9]><xml>
<w:LatentStyles DefLockedState="false" LatentStyleCount="156">
</w:LatentStyles>
</xml><![endif]--><!--[if gte mso 10]>
<style>
/* Style Definitions */
table.MsoNormalTable
{mso-style-name:"Normale Tabelle";
mso-tstyle-rowband-size:0;
mso-tstyle-colband-size:0;
mso-style-noshow:yes;
mso-style-parent:"";
mso-padding-alt:0cm 5.4pt 0cm 5.4pt;
mso-para-margin:0cm;
mso-para-margin-bottom:.0001pt;
mso-pagination:widow-orphan;
font-size:10.0pt;
font-family:"Times New Roman";
mso-ansi-language:#0400;
mso-fareast-language:#0400;
mso-bidi-language:#0400;}
</style>
<![endif]--></p>
<ul>
<li>';
$regex = '~<!--([\s\S]*?)-->~';
$replacement = '';
$newString = preg_replace($regex, $replacement, $string);
echo $newString;
?>