PHP preg_replace replace text unless inside brackets

只谈情不闲聊 提交于 2019-12-23 02:04:37

问题


I would like to use PHP's preg_replace() to search a text for occurrences of a certain word, and enclose that word in brackets, unless there are already brackets present. The challenge here is that I want to test for brackets that may or may not be directly adjacent to the text I am looking for.

Random example: I want to replace warfarin with [[warfarin]]

  1. in this string: Use warfarin for the prevention of strokes
  2. but not in this string: Use [[warfarin]] for the prevention of strokes (brackets already present)
  3. and not in this string either: Use [[generic warfarin formulation]] for the prevention of strokes ('remote' brackets already present)

I can satisfy the first two requirements all right using lookbehind and lookahead assertions:

php > echo preg_replace( "/(?<!\[\[)(warfarin)(?!]])/", "[[$1]]", "Use warfarin for the prevention of strokes" );
Use [[warfarin]] for the prevention of strokes
php > echo preg_replace( "/(?<!\[\[)(warfarin)(?!]])/", "[[$1]]", "Use [[warfarin]] for the prevention of strokes" );
Use [[warfarin]] for the prevention of strokes

But I need your help with the third requirement, i.e. not adding brackets when there are 'remote' brackets present:

php > echo preg_replace( "/(?<!\[\[)(warfarin)(?!]])/", "[[$1]]", "Use [[generic warfarin formulation]] for the prevention of strokes" );
Use [[generic [[warfarin]] formulation]] for the prevention of strokes

In this last example, the square brackets should not be added to the word warfarin since it is contained in a longer expression that is already enclosed in brackets.

The problem is that PHP's regexp assertions must have fixed length, otherwise it would be very simple.

I'm using

PHP 5.3.10-1ubuntu3.1 with Suhosin-Patch (cli) (built: May  4 2012 02:20:36)

Thanks in advance!


回答1:


This is what I would do.

$str = 'Use warfarin for the prevention of strokes. ';
$str .= 'Use [[warfarin]] for the prevention of strokes. ';
$str .= 'Use [[generic warfarin formulation]] for the prevention of strokes';
$arr = preg_split('/(\[\[.*?\]\])/',$str,-1,PREG_SPLIT_DELIM_CAPTURE);
// split the string by [[...]] groups
for ($i = 0; $i < count($arr); $i+=2) {
    // even indexes will give plain text parts
    $arr[$i] = preg_replace('/(warfarin)/i','[[$1]]',$arr[$i]);
    // enclose necessary ones by double brackets
}
echo '<h3>Original:</h3>' . $str;
$str = implode('',$arr); // finally join them
echo '<h3>Changed:</h3>' . $str;

will result in

Original:

Use warfarin for the prevention of strokes. Use [[warfarin]] for the prevention of strokes. Use [[generic warfarin formulation]] for the prevention of strokes

Changed:

Use [[warfarin]] for the prevention of strokes. Use [[warfarin]] for the prevention of strokes. Use [[generic warfarin formulation]] for the prevention of strokes




回答2:


Try this:

echo preg_replace( "/(warfarin)([^\]]+(\[|$))/", "[[$1]]$2", "Use generic warfarin[[ formulation for]] the prevention of strokes\n" );

I assume that there won't be any case of closing brackets without opening brackets.



来源:https://stackoverflow.com/questions/10672286/php-preg-replace-replace-text-unless-inside-brackets

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!