preg_match_all:获取引号内的文本,html标记中除外
我最近使用了一种模式,用成对的开始/结束双引号替换直接双引号preg_match_all:获取引号内的文本,html标记中除外,html,regex,tags,quotes,Html,Regex,Tags,Quotes,我最近使用了一种模式,用成对的开始/结束双引号替换直接双引号 $string = preg_replace('/(\")([^\"]+)(\")/','“$2”',$string); 如果$string是一个句子,甚至是一个段落,它就可以正常工作 但是 我的函数可以被调用到一块HTML代码的作业中,它不再作为例外工作: $string = preg_replace('/(\")([^\"]+)(\")/','“$2”','<a href="page.html">Somethi
$string = preg_replace('/(\")([^\"]+)(\")/','“$2”',$string);
如果$string是一个句子,甚至是一个段落,它就可以正常工作
但是
我的函数可以被调用到一块HTML代码的作业中,它不再作为例外工作:
$string = preg_replace('/(\")([^\"]+)(\")/','“$2”','<a href="page.html">Something "with" quotes</a>');
$string=preg\u replace(“/(\”)([^\“]+)(\”/”,“$2”,”;
返回
<a href=“page.html”>Something “with” quotes</a>
这是一个问题
所以我想我可以分两步完成:提取标签中的文本,然后替换引号
我试过这个
$pattern='/<[^>]+>(.*)<\/[^>]+>/';
$pattern='/]+>(.*]+>”;
例如,如果字符串是
$string='<a href="page.html">Something "with" quotes</a>';
$string='';
但它不适用于以下字符串:
$string='Something "with" quotes <a href="page.html">Something "with" quotes</a>';
$string='Something'加上“引号”;
有什么想法吗
Bertrand我想通常的回答是……正如已经发生的那样,您不应该通过正则表达式解析HTML。您可以查看以提取文本并应用正则表达式,从您已经说过的内容来看,它似乎工作得很好
本教程将为您指明正确的方向。我确信这将以一场火焰之战结束,但这是可行的:
echo do_replace('<a href="page.html">Something "with" quotes</a>')."\n";
echo do_replace('Something "with" quotes <a href="page.html">Something "with" quotes</a>')."\n";
function do_replace($string){
preg_match_all('/<([^"]*?|"[^"]*")*>/', $string, $matches);
$matches = array_flip($matches[0]);
$uuid = md5(mt_rand());
while(strpos($string, $uuid) !== false) $uuid = md5(mt_rand());
// if you want better (time) garanties you could build a prefix tree and search it for a string not in it (would be O(n)
foreach($matches as $key => $value)
$matches[$key] = $uuid.$value;
$string = str_replace(array_keys($matches), $matches, $string);
$string = preg_replace('/\"([^\"<]+)\"/','“$1”', $string);
return str_replace($matches, array_keys($matches), $string);
}
有了costum状态机,你甚至可以不用先替换,然后再替换回来。我还是建议使用解析器。我终于找到了一种方法:
$string=preg\u replace\u回调('/[^]*(?!([^)/sim',创建函数('$matches',返回preg\u replace(\'/(\'')([^\']+)(\'')/\',\'“$2”,$matches[0]),$string);
Bertrand,重新提出这个问题,因为它有一个简单的解决方案,可以让您一次完成替换,而无需回调。(在对有关的一般问题进行研究时发现了您的问题。)
下面是我们的简单正则表达式:
<[^>]*>(*SKIP)(*F)|"([^"]*)"
]*>(*跳过)(*F)|“([^”]*)”
交替的左侧匹配complete
,然后故意失败。右侧匹配双引号字符串,我们知道它们是右侧字符串,因为它们没有与左侧的表达式匹配
这段代码显示了如何使用正则表达式(请参见本部分底部的结果):
@Kolink我知道会出现这种情况。这就是为什么我建议使用simplexml,只将其应用于文本,而不应用于属性。我必须“清理”的字符串是90%大小写中文本字段的值,在某些情况下,您有“位”“内部的html代码。这就是解析不合适的原因。如果'Something'加引号'
,需要什么输出?'Something'加引号'
或'Something'使用引号“
?谢谢,但当我需要解析某些代码时,我会使用解析器。在这种情况下,解析代码不会帮助我用其他字符替换某些字符。我尝试过,它很有效。谢谢。问题是,在90%的时间里,我只得到一个字符串(文本输入的值)使用一个字符串或几个标记的解析器实际上需要做更多的工作。这个正则表达式不适用于完整的html页面。
$string = preg_replace_callback('/[^<>]*(?!([^<]+)?>)/sim', create_function('$matches', 'return preg_replace(\'/(\")([^\"]+)(\")/\', \'“$2”\', $matches[0]);'), $string);
<[^>]*>(*SKIP)(*F)|"([^"]*)"
<?php
$regex = '~<[^>]*>(*SKIP)(*F)|"([^"]*)"~';
$subject = 'Something "with" quotes <a href="page.html">Something "with" quotes</a>';
$replaced = preg_replace($regex,"“$1”",$subject);
echo $replaced."<br />\n";
?>