我是一个正确英语的坚持者(是的,我知道" stickler"" correct-ish"是矛盾的)。我已经在我公司的网站上创建了一个CMS,但有一件事情让我很紧张 - 创建" smart"发布内容中的引用。
我有一个reg-ex可以做到这一点,但是当我在副本中遇到html标签时遇到了问题。例如,我的CMS使用的一个已发布的故事可能包含一堆纯文本和一些HTML标记,例如链接标记,其中包含我不想更改为" smart&#34的引号;引用原因很明显。
15年前,我是Perl RegEx的王牌,但我在这个问题上完全不知所措。我想要做的是处理一个字符串,忽略html标签内的所有文本,用" smart"替换字符串中的所有引号。引号,然后返回其html标签完整的字符串。
我有一个功能,我拼凑在一起处理我遇到的CMS最常见的情况,但我讨厌它丑陋而不优雅,如果出现无法预料的标签,我的解决方案完全休息。
这里有代码(请不要笑,它被砸在半瓶苏格兰威士忌上):
function educate_quotes($string) {
$pattern = array('/\b"/',//right double
'/"\b/',//left double
'/"/',//left double end of line
"/(\w+)'(\w+)/",//apostrophe
"/\b'/",//left single
"/'\b/",//right single
"/'$/",//right single end of line
"/--/"//emdash
);
$replace = array("”",//right double quote
"“",//left double
"”",//left double end of line
"$1"."’"."$2",//apostrophe
"’",//left single
"‘",//right single
"’",//right single end of line
"—"//emdash
);
$string = preg_replace($pattern,$replace,$string);
//remove smart quotes around urls
$string = preg_replace("/href=“(.+)”/","href=\"$1\"",$string);
//remove smart quotes around images
$string = preg_replace("/src=“(.+?)”/","src=\"$1\" ",$string);
//remove smart quotes around alt tags
$string = str_replace('alt=”"','',$string);
$pat = "/alt=“(.+?)”/is";
$rep = "alt=\"$1\" ";
$string = preg_replace($pat,$rep,$string);
//i'm too lazy to figure out why this artifact keeps appearing
$string = str_replace("alt=“",'alt="',$string);
//same thing here
$string = preg_replace("/” target/","\" target",$string);
return $string;
}
就像我说的那样,我知道代码是丑陋的,我可以接受更优雅的解决方案。它有效,但在将来,如果出现无法预料的标签,它将会中断。为了记录,我想重申一下,我并没有试图获得PARSE html标签的正则表达式;在解析字符串中所有其余文本时,我试图将它们发送到IGNORE。
任何解决方案?我已经做了大量的在线搜索,似乎无法找到解决方案,而且我对PHP的正则表达式的实现已经非常不熟悉了。 p>
答案 0 :(得分:0)
行。在Slacks建议DOM解析之后,我回答了我自己的问题,但是现在我遇到了正则表达式不能处理创建的字符串的问题。这是我的代码:
function educate_quotes($string) {
$pattern = array(
'/"(\w+)"/',//quotes
"/(\w+)'(\w+)/",//apostrophe
"/'(\w+)'/",//single quotes
"/'\b/",//right single
"/--/"//emdash
);
$replace = array(
"“"."$1"."”",//quotes
"$1"."’"."$2",//apostrophe
"’"."$1"."‘",//single quotes
"‘",//right single
"—"//emdash
);
$xml = new DOMDocument();
$xml->loadHTML($string);
$text = (string)$xml->textContent;
$smart = preg_replace($pattern,$replace,$text);
$xml->textContent = $smart;
$html = $xml->saveHTML();
return $html;
}
DOM解析工作正常;问题是现在我的正则表达式(我已经从上面的那个改变了,但直到上面的那个已经没有处理创建的新字符串)实际上并没有替换字符串中的任何引号。
此外,当字符串中包含不完整的HTML代码时,我收到以下恼人的警告:
Warning: DOMDocument::loadHTML() [domdocument.loadhtml]: Unexpected end tag : p in Entity, line: 2 in /home/leifw/now/cms_functions.php on line 418
由于我不能指望记者总是使用完美的HTML代码,这也是一个问题。
答案 1 :(得分:0)
是否可以根据html <
>
标记进行拆分,然后将其重新组合在一起?
$text = "<div sdfas=\"sdfsd\" >ksdfsdf\"dfsd\" dfs </div> <span sdf='dsfs'> dfsd 'dsf ds' </span> ";
$new_text = preg_split("/(<.*?>)/", $text, -1, PREG_SPLIT_DELIM_CAPTURE);
echo htmlspecialchars(print_r($new_text, 1));
所以你得到的是:
Array
(
[0] =>
[1] => <div sdfas="sdfsd" >
[2] => ksdfsdf"dfsd" dfs
[3] => </div>
[4] =>
[5] => <span sdf='dsfs'>
[6] => dfsd 'dsf ds'
[7] => </span>
[8] =>
)
然后你可以做的就是将整个事情重新组合在一起,同时使用preg_replace,如果它没有<
>
。
答案 2 :(得分:0)
使用A. Lau的建议,我认为我有一个解决方案,结果它实际上是正则表达式,而不是xml解析器。
这是我的代码:
$string = '<p>"This" <b>is</b> a "string" with <a href="http://somewhere.com">quotes</a> in it. <img src="blah.jpg" alt="This is an alt tag"></p><p>Whatever, you know?</p>';
$new_string = preg_split("/(<.*?>)/",$string, -1, PREG_SPLIT_DELIM_CAPTURE);
echo "<pre>";
print_r($new_string);
echo "</pre>";
for($i=0;$i<count($new_string);$i++) {
$str = $new_string[$i];
if ($str) {
if (strpos($str,"<") === false) {
$new_string[$i] = convert_quotes($str);
}
}
}
$str = join('',$new_string);
echo $str;
function convert_quotes($string) {
$pattern = array('/\b"/',//right double
'/"\b/',//left double
'/"/',//left double end of line
"/(\w+)'(\w+)/",//apostrophe
"/\b'/",//left single
"/'\b/",//right single
"/'$/",//right single end of line
"/--/"//emdash
);
$replace = array("”",//right double quote
"“",//left double
"”",//left double end of line
"$1"."’"."$2",//apostrophe
"’",//left single
"‘",//right single
"’",//right single end of line
"—"//emdash
);
return preg_replace($pattern,$replace,$string);
}
该代码输出以下内容:
数组(
> [0] =>
> [1] => <p>
> [2] => "This"
> [3] => <b>
> [4] => is
> [5] => </b>
> [6] => a "string" with
> [7] => <a href="http://somewhere.com">
> [8] => quotes
> [9] => </a>
> [10] => in it.
> [11] => <img src="blah.jpg" alt="This is an alt tag">
> [12] =>
> [13] => </p>
> [14] =>
> [15] => <p>
> [16] => Whatever, you know?
> [17] => </p>
> [18] => >
> Whatever, you know?
“This”是一个带有引号的“字符串”。这是一个alt标签
无论如何,你知道吗?