我正在尝试从公告板中删除嵌套引用,但我遇到了一些问题。
示例输入:
[quote author = personX link = topic = 12.msg1910#msg1910 date = 1282745641]
[quote author=PersonY link=topic=12.msg1795#msg1795 date=1282727068] The message in the original quote [/quote]
引用第一条消息的第二条消息
[/报价]
[quote author = PersonZ link = topic = 1.msg1#msg1 date = 1282533805]
随机第三个引用
[/报价]
示例输出
[quote author = personX link = topic = 12.msg1910#msg1910 date = 1282745641]
第二个引文中的消息
[/报价]
[quote author = PersonZ link = topic = 1.msg1#msg1 date = 1282533805]
随机第三个引用
[/报价]
正如您所看到的,嵌入的引用(原始消息)以及引号标记已被删除。
我似乎无法弄明白。
当我尝试
时$toRemove = '(\\[)(quote)(.*?)(\\])';
$string = $txt;
$found = 0; echo preg_replace("/($toRemove)/e", '$found++ ? \'\' : \'$1\'', $string);
除去第一个引号标记
之外,它会删除每个引号标记但是当我将代码扩展为:
$toRemove = '(\\[)(quote)(.*?)(\\])(.*?)(\\[\\/quote\\])';
$string = $txt;
$found = 0; echo preg_replace("/($toRemove)/e", '$found++ ? \'\' : \'$1\'', $string);
它完全没有做任何事情。
有关于此的任何想法吗?
编辑:
感谢您的帮助,Haggi。
尽管如此,我仍然遇到麻烦。
围绕
的while循环while ( $input = preg_replace_callback( '~\[quoute.*?\[/quote\]~i', 'replace_callback', $input ) ) {
// replace every occurence
}
导致页面无限循环,当删除时(以及quoute中的额外u),页面不会执行任何操作。
我已确定原因是匹配的
更改为
时$input = preg_replace_callback( '/\[quote(.*?)/i', 'replace_callback', $input );
代码确实开始工作,但是当更改为
时$input = preg_replace_callback( '/\[quote(.*?)\[\/quote\]/i', 'replace_callback', $input );
它停止再做任何事情。
此外,undo_replace函数存在问题,因为它永远不会找到存储的哈希值,它只会提供有关未完成索引的警告。匹配sha1的正则表达式无法正常工作。
我现在拥有的完整代码:
$cache = array();
$input = $txt;
function replace_callback( $matches ) {
global $cache;
$hash = sha1( $matches[0] );
$cache["hash"] = $matches[0];
return "REPLACE:$hash";
}
// replace all quotes with placeholders
$input = preg_replace_callback( '/\[quote(.*?)\[quote\]/i', 'replace_callback', $input );
function undo_replace( $matches ) {
global $cache;
return $cache[$matches[1]];
}
// restore the outer most quotes
$input = preg_replace_callback( '~REPLACE:[a-f0-9]{40}~i', 'undo_replace', $input );
// remove the references to the inner quotes
$input = preg_replace( '~REPLACE:[a-f0-9]{40}~i', '', $input );
echo $input;
再次感谢任何想法的人:)
答案 0 :(得分:2)
第一个是唯一一个很容易找到的人:
'$found++ ? \'\' : \'$1\''
当启动$ found未定义并且计算结果为false时返回$ 1。然后$ found增加到1(undefined + 1 = 1),因此它大于零,每次调用它时,它会进一步递增。因为所有与零不同的东西在之后被评估为真,所以你总是得到''返回。
你想做的是这样的事情
$cache = array();
function replace_callback( $matches ) {
global $cache;
$hash = sha1sum( $matches[0] );
$cache[$hash] = $matches[0];
return "REPLACE:$hash";
}
// replace all quotes with placeholders
$count = 0;
do {
$input = preg_replace_callback( '~\[quoute.*?\[/quote\]~i', 'replace_callback', $input, -1, $count );
// replace every occurence
} while ($count > 0);
function undo_replace( $matches ) {
global $cache;
return $cache[$matches[1]];
}
// restore the outer most quotes
$input = preg_replace_callback( '~REPLACE:[a-f0-9]{40}~i', 'undo_replace', $input );
// remove the references to the inner quotes
$input = preg_replace( '~REPLACE:[a-f0-9]{40}~i', '', $input );
此代码未经测试,因为我手头没有PHP来测试它。如果您有任何错误无法修复,请在此处发布,我会修复它们。
干杯,
haggi
答案 1 :(得分:0)
我用preg_replace为嵌套引号搜索了几个解决方案,但没有人工作。所以我根据我的要求尝试了我的小版本。
$position = strrpos($string, '[/quote:'); // this will get the position of last quote
$text = substr(strip_tags($string),$position+17); // this will get the data after the last quote used.
希望这会对某人有所帮助。