什么正则表达式可以识别HTML标记之外的双引号(已经过验证)以将它们转义为"
?
答案 0 :(得分:6)
没有这样的正则表达。
<p>
<!-- <a href=" --> is this outside " a tag <!-- "> foo </a> --> or not?
</p>
如果你想这样做,你将不得不使用HTML解析器。由于您已经验证了HTML,因此您可能已经使用了解析器。
答案 1 :(得分:1)
不要使用正则表达式,使用(或写入)解析器。
以下代码假定输入HTML字符串格式正确(如您所述)。请注意,如果遇到无效输入,代码将会中断!
如果您无法确定格式良好,可以尝试PHP Tidy。
<?php
$html = '<tag>text "text"<tag attr="value"><!-- "text" --> text</tag> "text".';
echo html_escape_quotes($html);
/* Parses input HTML and escapes any literal double quotes
in the text content with ". Leaves comments alone. */
function html_escape_quotes($html)
{
$output = "";
$length = strlen($html);
$delim = "<";
$offset = 0;
while ($offset < $length) {
$tokpos = strpos($html, $delim, $offset);
if ($tokpos === false) $tokpos = $length;
$token = substr($html, $offset, $tokpos - $offset);
$offset = $tokpos;
if ($delim == "<") {
$token = str_replace('"', '"', $token);
$delim = substr($html, $offset, 4) == "<!--" ? "-->" : ">";
} else {
$delim = "<";
}
$output .= $token;
}
return $output;
}
?>
答案 2 :(得分:0)
\"(?!\s*\w*>)
答案 3 :(得分:0)
它可能。
你可以用regexp做到这一点,有些东西类似于下面。你将不得不多次运行它,因为这个正则表达式只替换了标签之间的1“with”。
Serach: (\<.+?\>.+?)(")(.+?\</.+?\>)
Replace: $1'$3
但是,更好的方法是利用回调来进行功能替换。只需创建将标签内容发送到函数的RE,然后可以简单地将“替换为您想要的任何内容。”
查看更多信息here。搜索回调。 正如derobert所指出的那样,您可能需要在此之前删除评论:)
答案 4 :(得分:0)
您可以尝试拆分字符串,并使用以下表达式将标记与文本数据分开:
<(?:\?[^?]+\?>|[A-Za-z]+(?:[^">]+|"[^"]*")*|!(?:\[CDATA\[(?:[^\]]+|](?:[^\]]|][^>]))*]]|--(?:[^-]+|-(?!->))*--))>
这将(希望)匹配任何XML PI,元素标记,CDATA和注释块。
所以:
$parts = preg_split('/(<(?:\?[^?]+\?>|[A-Za-z]+(?:[^">]+|"[^"]*")*|!(?:\[CDATA\[(?:[^\]]+|](?:[^\]]|][^>]))*]]|--(?:[^-]+|-(?!->))*--))>)/', $str, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE);
$str = '';
foreach ($parts as $part) {
if ($part[0] == '<') {
$str .= $part;
} else {
$str .= str_replace('"', '"', $part);
}
}
但我怀疑这是非常有效的。一个真正的解析器会更有效和正确。
答案 5 :(得分:0)
不是最好的(不适用于所有情况)但对我来说足够好:
function quoting(&$data) {
$quot = '(["\x93\x94\x84]|\“|\„|\”|\“|\„|\”|\&quo;|\")';
$parse = '<q>$2</q>';
$data = preg_replace('/="([^"]*)"/', '*%Q:$1%*', $data);
$data = preg_replace("/$quot(.*?)$quot/", $parse, $data);
$data = preg_replace('/\*%Q:(.*?)%\*/', '="$1"', $data);
}