我最近使用了一种模式来用成对的开/关双引号替换直双引号。
$string = preg_replace('/(\")([^\"]+)(\")/','“$2”',$string);
当$ string是一个句子,甚至是段落时,它工作正常。
但是...
我的函数可以被调用到一大堆HTML代码的作业,并且它不再作为例外工作了:
$string = preg_replace('/(\")([^\"]+)(\")/','“$2”','<a href="page.html">Something "with" quotes</a>');
返回
<a href=“page.html”>Something “with” quotes</a>
那是一个问题...
所以我认为我可以通过两次传递:在标签中提取文本,然后替换引号。
我试过这个
$pattern='/<[^>]+>(.*)<\/[^>]+>/';
例如,如果字符串是
,它就可以工作$string='<a href="page.html">Something "with" quotes</a>';
但它不适用于像:
这样的字符串$string='Something "with" quotes <a href="page.html">Something "with" quotes</a>';
有什么想法吗?
贝特朗
答案 0 :(得分:1)
通常的回复我猜...因为它已经pointed out,所以你不应该通过正则表达式解析HTML。您可以查看PHP Simple DOM Parse来提取文本并应用您正在使用的正则表达式,这些正则表达式似乎正常工作。
This教程应该让你朝着正确的方向前进。
答案 1 :(得分:0)
我很确定这将以火焰战结束,但这有效:
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);
}
输出(我替换了&amp; ldquo;和&amp; rdquo;与“
和”
):
<a href="page.html">Something “with” quotes</a>
Something “with” quotes <a href="page.html">Something “with” quotes</a>
使用costum状态机你甚至可以在没有第一次更换的情况下完成它而不是替换它。无论如何,我建议使用Parser。
答案 2 :(得分:0)
我终于找到了办法:
码
$string = preg_replace_callback('/[^<>]*(?!([^<]+)?>)/sim', create_function('$matches', 'return preg_replace(\'/(\")([^\"]+)(\")/\', \'“$2”\', $matches[0]);'), $string);
答案 3 :(得分:0)
这是我们简单的正则表达式:
<[^>]*>(*SKIP)(*F)|"([^"]*)"
交替的左侧匹配完成<tags>
然后故意失败。右侧匹配双引号字符串,我们知道它们是正确的字符串,因为它们与左侧的表达式不匹配。
此代码显示了如何使用正则表达式(请参阅online demo底部的结果):
<?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";
?>
参考
How to match (or replace) a pattern except in situations s1, s2, s3...