0

我最近使用了一种模式,通过成对的打开/关闭双引号替换直双引号。

$string = preg_replace('/(\")([^\"]+)(\")/','“$2”',$string);

当 $string 是一个句子,甚至是一个段落时,它工作得很好。

但是……</p>

我的函数可以被调用来处理一大段 HTML 代码,但它不再像例外一样工作:

$string    = preg_replace('/(\")([^\"]+)(\")/','“$2”','<a href="page.html">Something "with" quotes</a>');

返回

<a href=“page.html”&gt;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>';

任何想法?

伯特兰

4

4 回答 4

1

我猜通常的答复...正如已经指出的那样,您不应该通过正则表达式解析 HTML。您可以查看PHP Simple DOM Parse以提取文本并应用您的正则表达式,从您已经说过的内容来看,它似乎工作得很好。

教程应该让您朝着正确的方向前进。

于 2013-09-25T14:27:17.350 回答
0

Bertrand,重新提出了这个问题,因为它有一个简单的解决方案,可以让您一次性完成替换 - 无需回调。(在对有关如何在 regex 中排除模式的一般问题进行一些研究时发现了您的问题。)

这是我们的简单正则表达式:

<[^>]*>(*SKIP)(*F)|"([^"]*)"

交替匹配的左侧完成<tags>然后故意失败。右边匹配双引号字符串,我们知道它们是正确的字符串,因为它们没有被左边的表达式匹配。

这段代码展示了如何使用正则表达式(见在线演示底部的结果):

<?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";
?>

参考

如何匹配(或替换)模式,除了情况 s1、s2、s3...

于 2014-05-21T06:32:22.817 回答
0
于 2013-09-25T15:27:29.123 回答
0

我终于找到了一种方法:

  1. 提取可以在任何标签(如果有)内部或外部(之前、之后)的文本
  2. 使用回调逐对查找引号并替换它们。

代码

$string = preg_replace_callback('/[^<>]*(?!([^<]+)?>)/sim', create_function('$matches',  'return preg_replace(\'/(\")([^\"]+)(\")/\', \'“$2”\', $matches[0]);'), $string);
于 2013-09-26T09:35:51.643 回答