Regex results in “Delimiter must not be alphanumeric or backslash” [duplicate]

白昼怎懂夜的黑 提交于 2019-12-20 06:03:35

问题


I have this code

function a($menu_item, $remove_link) {
    $pattern = 'class="(.+)"(.+)<a.+>(.+)</a>';
    if($remove_link) {
        return preg_replace($pattern, 'class="$1 selected"$2$3', $menu_item); //<- line 6
    }
    return $menu_item;
}

Which basically checks if $remove_link is true, and then removes the link and adds a class definition to $menu_item

For example, if i use

$menu_item = '<li class="menuitem first"><a href="index.php">Home</a></li>';
$menu_item = a($menu_item, true);

It should return

<li class="menuitem first selected">Home</li>;

The regex is tested and it works in Notepad++, but my function is giving this error:

Warning: preg_replace(): Delimiter must not be alphanumeric or backslash in functions.php on line 6

I saw that php patterns have to be "delimited" with slashes, so i tried to use class="/(.+)"(.+)<a.+>(.+)/</a> instead, but it gives the same error.

What am i missing? How do i use delimiters properly?


回答1:


you must put pattern delimiters at the begining and at the end of the pattern, example:

$pattern = '#class="(.+)"(.+)<a.+>(.+)</a>#';

Here # is a better choice than / because you avoid to escape all the slashes inside your pattern, but you can write:

$pattern = '/class="(.+)"(.+)<a.+>(.+)<\/a>/';

As an aside comment, your pattern will cause many backtracks:

$pattern = '~class="([^"]+)"([^>]*>)<a[^>]+>([^<]+)</a>~';

will work better.

Keep in mind that + and * are by default greedy quantifiers (i.e. they take all they can).

If I use a restricted character class instead of the dot, I can stop the greediness of the quantifiers, example

[^"]+ take all characters except ", thus it stop when a " is find.

Demo:

<?php
function a($menu_item, $remove_link) {
    //$pattern = '~class="(.+)"(.+)<a.+>(.+)</a>~';
    $pattern = '~class="([^"]+)"([^>]*>)<a[^>]+>([^<]+)<\/a>~';
    if($remove_link) {
        return preg_replace($pattern, 'class="$1 selected"$2$3', $menu_item);
    }
    return $menu_item;
}

$menu_item = '<li class="menuitem first"><a href="index.php">Home</a></li>';
echo a($menu_item, true);


来源:https://stackoverflow.com/questions/18431001/regex-results-in-delimiter-must-not-be-alphanumeric-or-backslash

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