开发者

I need help with this regex pattern

开发者 https://www.devze.com 2023-03-10 15:47 出处:网络
Hi I have a problem with my regex pattern: preg_match_all(\'/!!\\d{3}/\', \'!!333!!33开发者_开发百科3 !!333 test\', $result);

Hi I have a problem with my regex pattern:

preg_match_all('/!!\d{3}/', '!!333!!33开发者_开发百科3 !!333 test', $result);

I want this to match !!333 but not !!333!333. How can I modify this regex to match only a max length of 5 characters - two ! and three numbers.


/^!!\d{3}$/

You need the anchors ^, that match the beginning of a string and $ for the end. Its like saying: "It must begin at the start of the string and it must end at the end of it." If you omit one (or both) the pattern allows arbitrary symbols at the beginning and/or the end.

Update

As I found out in the comments the question was very misleading. Now I suggest to split the string before applying the pattern

$string = '!!333!!333 !!333 test';
$result = array();
foreach (explode(' ', $string) as $index => $item) {
  if (preg_match('/^!!\d{3}$/', $item)) {
    $result[$index] = $item;
  }
}

This also respects the index of the item. If you dont need it, remove the $index stuff or just ignore it ;)

Its much easier then trying to find a pattern, that fulfill your request all at once.


^!!\d{3}$

You need to anchor your pattern.

If you want to match a string with !!333 in it, you may want something like:

(^|\s)!!\d{3}($|\s)

With further explanation we can have a further refinement:

(^|\s)!!\d{3}(?=$|\s)

Which will not capture the trailing space allowing multiple matches in the same line to match one after another.


I find the easiest and most descriptive way to do this is with negative lookaheads and lookbehinds.

See:

preg_match_all('/(?<![^\s])!!\d{3}(?![^\s])/', '!!333 !!333!!333 !!333 test !!333', result);

This says: match anything of the form !![0-9][0-9][0-9] which doesn't have anything other than a space in front or behind it. Note that these lookaheads/lookbehinds aren't matched themselves, they are "zero-width assertions", they are thrown away and so you only get "!!333" etc in your match, not " !!333" etc.

It returns

[0] => Array
        (
            [0] => !!333
            [1] => !!333
            [2] => !!333
        )

)

Also

preg_match_all(
    '/(?<![^\s])!!\d{3}(?![^\s])/', 
    '!!333 !!555 !!333 !!123 !!555 !!456 !!333 !!333 !!444 !!444 !!123 !!123 !!123!!123',
    $result));

returns

[0] => Array
    (
        [0] => !!333
        [1] => !!555
        [2] => !!333
        [3] => !!123
        [4] => !!555
        [5] => !!456
        [6] => !!333
        [7] => !!333
        [8] => !!444
        [9] => !!444
        [10] => !!123
        [11] => !!123
    )

That is, all but the last two which are too long.

See Lookahead tutorial.

0

精彩评论

暂无评论...
验证码 换一张
取 消