Php preg_replace和&;之间的结果不同;预赛
我有一个支持hashtags的论坛。我使用下面的行将所有的hashtag转换成链接。我使用Php preg_replace和&;之间的结果不同;预赛,php,regex,preg-replace,preg-match-all,Php,Regex,Preg Replace,Preg Match All,我有一个支持hashtags的论坛。我使用下面的行将所有的hashtag转换成链接。我使用(^ | \(|\s |>)模式来避免在URL中拾取命名锚 $str=preg_replace("/(^|\(|\s|>)(#(\w+))/","$1<a href=\"/smalltalk.php?Tag=$3&".SID."\">$2</a>",$str); 使用m和s修饰符没有任何区别。第二种情况下我做错了什么 编辑:输入文本可以是纯文本或HTML。问题
(^ | \(|\s |>)
模式来避免在URL中拾取命名锚
$str=preg_replace("/(^|\(|\s|>)(#(\w+))/","$1<a href=\"/smalltalk.php?Tag=$3&".SID."\">$2</a>",$str);
使用m
和s
修饰符没有任何区别。第二种情况下我做错了什么
编辑:输入文本可以是纯文本或HTML。问题输入示例:
#startoftextreplacesandmatches #afterwhitespacereplacesandmatches <b>#insidehtmltagreplacesandmatches</b> :)
#startofnewlinereplacesbutdoesnotmatch :(
#开始文本替换和匹配#在空格替换和匹配之后#内部HTML替换和匹配:)
#StartToNewlineReplacesButDoesNotMatch:(
您的替换操作有一个您显然还没有遇到的问题-它将允许未替换的HTML特殊字符通过。我之所以知道这一点,是因为您的正则表达式允许哈希标记前缀为
,这是一个特殊字符
因此,我建议您使用此代码进行替换,这将作为提取要插入数据库的标记的代码:
$hashtags = array();
$expr = '/(?:(?:(^|[(>\s])#(\w+))|(?P<notag>.+?))/';
$str = preg_replace_callback($expr, function($matches) use (&$hashtags) {
if (!empty($matches['notag'])) {
// This takes care of HTML special characters outside hashtags
return htmlspecialchars($matches['notag']);
} else {
// Handle hashtags
$hashtags[] = $matches[2];
return htmlspecialchars($matches[1]).'<a href="/smalltalk.php?Tag='.htmlspecialchars(urlencode($matches[2])).'&'.SID.'">#'.htmlspecialchars($matches[2]).'</a>';
}
}, $str);
$hashtags=array();
$expr='/(?:(?:(^ |[(>\s])#(\w+)|(?P.+)/”;
$str=preg_replace_回调($expr,function($matches)use(&$hashtags){
如果(!empty($matches['notag'])){
//这将处理hashtags之外的HTML特殊字符
返回htmlspecialchars($matches['notag']);
}否则{
//句柄哈希标记
$hashtags[]=$matches[2];
返回htmlspecialchars($matches[1])。';
}
}美元/平方米);
运行上述代码后,$str
将包含修改后的字符串,并正确转义以直接输出,$hashtags
将填充所有匹配的标记
标签放在哪种文本中?纯文本?HTML?BBCode?标记?刻在石板上的字母?文本可以是纯文本或HTML。对于HTML,我建议您应该注意文本中的标签,如:
a#tag this is
,可能是标签#tag
。如果是这样的话(或其他一些可能发生的常见事件),您可能对这个问题和答案感兴趣:尝试测试,但得到了解析错误:语法错误,第180行的/blahblahblah/smallpost.php中出现意外的T_函数。输入文本可能已经是TinyEditor中的HTML,在我点击此代码之前,我已经去除了不需要的标记和转义了必要的字符。preg_替换正在工作,它正在运行preg_match_不是所有的。@user1641839在这种情况下,同样的原则适用,它只是意味着它可以简化:@user1641839解析错误是因为您使用的是PHP<5.3,一秒钟后我会给您一个工作版本that@user1641839好的,这个怎么样?-我必须把它包装在一个对象中,因为PHP5.2没有r从当前作用域继承变量。我知道您现有的替换代码正在工作,但我的观点是,通过将其与标记搜索相结合,您可以解决您的问题,并且使您的代码更高效,因为您只需运行一次正则表达式。在处理此代码的过程中,我发现了真正的问题-匹配在通过中断换行符的sql插入之前,在对文本进行转义之后执行,替换没有这样的转义,因为它是对表中的文本执行的,doh!您的代码效率更高,这是对的,因此我将使用它。感谢您的帮助。
$hashtags = array();
$expr = '/(?:(?:(^|[(>\s])#(\w+))|(?P<notag>.+?))/';
$str = preg_replace_callback($expr, function($matches) use (&$hashtags) {
if (!empty($matches['notag'])) {
// This takes care of HTML special characters outside hashtags
return htmlspecialchars($matches['notag']);
} else {
// Handle hashtags
$hashtags[] = $matches[2];
return htmlspecialchars($matches[1]).'<a href="/smalltalk.php?Tag='.htmlspecialchars(urlencode($matches[2])).'&'.SID.'">#'.htmlspecialchars($matches[2]).'</a>';
}
}, $str);