“[5|五][提示|建议]一次难忘的旅行|五 一次不后悔的旅行的建议|[5|五] [提示|建议] 一次[令人惊叹|难以置信]的旅行|五个[提示|建议] 令人惊奇的旅行”
到
“[5|五][小贴士|建议]一次难忘的旅行~五 一次不后悔的旅行的建议~[5|五] [提示|建议] 一次[令人惊叹|难以置信]的旅行〜五个[提示|建议] 令人惊奇的旅行”
我可以使用
str_replace("|", "~", $code)
,但问题是我不想将"|"
转换为"~"
(如果它在"[ ]"
之间)。
for($i=0,$s=strlen($str),$c=0;$i<$s;++$i){
if($str[$i]=='[')++$c;
elseif($str[$i]==']')--$c;
elseif(!$c && $str[$i]=='|')$str[$i]='~';
}
$in = "[5|five] [Tips|Suggestions] for an Unforgettable Trip|Five suggestions for a un-regret able Trip|[5|five] [tips|suggestions] for an [amazing|incredible] Trip|Five [tips|suggestions] for an astonishing Trip";
$out = preg_replace('/(?<=^|\])([^\[]*?)\|([^\[]*?)(?=\[|$)/s', '\1~\2', $in);
正则表达式的工作原理如下,只要不嵌套括号就正确(
[foo [bar]]
)。
- 从字符串的开头或在(?<=^|\])
]
之后开始- 捕获任意数量的不是([^\[]*?)
[
的字符- 我们要替换的角色\|
- 捕获任意数量的不是([^\[]*?)
的字符(再次)[
- 在字符串末尾或(?=\[|$)
之前停止匹配[
这个正则表达式应该做你想要的事情
/^(?<!\[.)\|(?!].)/
结合
preg_replace
和 klabamo 你就得到了:)
现在看来效果好多了!
$sentence = "[5|five] [Tips|Suggestions] for an Unforgettable Trip~Five suggestions for a un-regret able Trip~[5|five] [tips|suggestions] for an [amazing|incredible] Trip~Five [tips|suggestions] for an astonishing Trip";
$newSentence = preg_replace("/^(?<!\[.)\|(?!].)/", "~", $sentence);
echo $newSentence;
您可以先用str_replace替换所有,然后重新替换里面的那些
[]
(演示):
$subject = '[5|five] [Tips|Suggestions] for an Unforgettable Trip|Five suggestions for a
un-regret able Trip|[5|five] [tips|suggestions] for an [amazing|incredible] Trip|Five [tips|suggestions] for an astonishing Trip';
$result = str_replace('|', '~', $subject);
$pattern = '((\[[^\]]*)~([^\[]*\]))';
$result = preg_replace($pattern, '$1|$2', $result);
var_dump($subject, $result);
如果您知道方括号将始终保持适当平衡并且从不嵌套,那么您只需要简单的前瞻:
$after = preg_replace('/\|(?![^][]*+\])/', '~', $before);
从管道字符之后立即开始,先行扫描下一个右方括号。如果它首先没有看到 left 方括号就找到了一个,则该管道必须位于一对括号内。无需使用后向检查左括号,这很好,因为 PHP(与大多数正则表达式风格一样)不支持可变宽度后向。
我使用了负前瞻,但是正前瞻也可以工作:
$after = preg_replace('/\|(?=[^][]*+(?:\[|$))/', '~', $before);
请注意,如果右方括号是列出的第一个字符(或者在本例中是否定
^
之后的第一个字符),则无需转义字符类中的右方括号。因此,看起来奇怪的 [^][]
表示“不是方括号”。 *+
是一个 所有格量词。
如果方括号可以嵌套,你应该忘记正则表达式并使用@RiaD的解决方案。也许仍然可以使用正则表达式,但会复杂得多。
您可以使用 PHP preg_match 并与 str_replace 结合使用 - 我不是正则表达式专家,所以我无法为您编写任何内容。