3

How can I count patterns matching [] or [7] in PHP?

I need to match specific patterns in different strings like in the following examples:

Lorem ipsum dolor sit amet, consectetur [] adipiscing elit. Phasellus quis lectus metus, at posuere neque.

and

Lorem ipsum dolor sit amet, consectetur [23] adipiscing elit. Phasellus quis lectus metus, at posuere neque. Sed pharetra nibh [24] eget orci convallis at posuere leo convallis. Sed blandit augue [25] vitae augue scelerisque bibendum. Vivamus sit amet libero turpis, non venenatis urna. In blandit, odio convallis suscipit venenatis, ante ipsum cursus [26] augue.

In the first example, the empty [] will indicate a single point where the pattern needs to be matched and the string replaced.

The second example has numbers indicating multiple unique points where the strings need to be matched and replaced with unique content.

I am successfully matching the first example using the following code:

preg_replace('[]', $replacement, $fulltext);

but, I'm not sure how to match the numbers which are different for other text to be processed.

2 Answers 2

2

Your solution is just to do a preg replace with optional digits

preg_replace('/\[\d*\]/', $replacement, $fulltext);
Sign up to request clarification or add additional context in comments.

2 Comments

You do understand that your brackets are treated as delimiters here, right? Meaning, this is no different than saying preg_replace('/\d*/', $replacement, $fulltext);
You escaped the brackets, which is correct, but please note that this is still invalid since you still have no delimiters. The expression is correct, you just still need the delimiters or preg_replace will fail with an error of Delimiter must not be alphanumeric or backslash. If fixed in the answer I would upvote.
0

TL;DR;

You don't need preg_replace for this. Use str_replace instead.

See below for more detailed explanation.


It's probably important to note that brackets [] have special meaning in PCRE syntax as they indicate character classes. Which means that your pattern probably isn't doing what you expect it to do here.

For example

preg_replace('[]', 'foo', 'Lorem ipsum dolor sit amet, consectetur [] adipiscing elit. Phasellus quis lectus metus, at posuere neque.')

will give you

"fooLfooofoorfooefoomfoo fooifoopfoosfooufoomfoo foodfooofoolfooofoorfoo foosfooifootfoo fooafoomfooefootfoo,foo foocfooofoonfoosfooefoocfootfooefootfooufoorfoo foo[foo]foo fooafoodfooifoopfooifoosfoocfooifoonfoogfoo fooefoolfooifootfoo.foo fooPfoohfooafoosfooefoolfoolfooufoosfoo fooqfooufooifoosfoo foolfooefoocfootfooufoosfoo foomfooefootfooufoosfoo,foo fooafootfoo foopfooofoosfooufooefoorfooefoo foonfooefooqfooufooefoo.foo"

which is not likely what you want at all.

This is because PCRE also requires delimiters enclosing the pattern. Here the brackets will be treated as delimiters and you end up with an empty pattern.

It is also possible to use bracket style delimiters where the opening and closing brackets are the starting and ending delimiter, respectively. (), {}, [] and <> are all valid bracket style delimiter pairs.

Instead you should use

preg_replace('/\[\d*\]/', $replacement, $fulltext);

This escapes the brackets with the \ backslash character for literals and provides an optional number of digit characters to fall within the pattern matching expression.

If you wish for the replacement string to fall within the brackets themselves and not replace the actual brackets you can enclose the pattern in round braces and use back references to do the replacement.

If you want to match specific patterns to specific replacement strings (where the pattern is more complex than just a simple substring search/replace) then you should use preg_replace_callback_array instead. However, it's important to note that this function is only available in PHP 7

Example

$newText = preg_replace_callback_array(
               [
                   '/\[(23)\]/' => function ($match) {
                       return 'foo';
                   },
                   '/\[(24)\]/' => function ($match) {
                       return 'bar';
                   },
               ],
               $fulltext
           );

Which would give you something like...

"Lorem ipsum dolor sit amet, consectetur foo adipiscing elit. Phasellus quis lectus metus, at posuere neque. Sed pharetra nibh bar eget orci convallis at posuere leo convallis. Sed blandit augue [25] vitae augue scelerisque bibendum. Vivamus sit amet libero turpis, non venenatis urna. In blandit, odio convallis suscipit venenatis, ante ipsum cursus [26] augue."

If what you really need is to do replacement based on substring search (such that [23] will be replaced with the string 'foo' and [24] will be replaced with the string 'bar', etc...) then you don't need a regular expression. Instead you can use str_replace for this.

Here's an example...

$fulltext = 'Lorem ipsum dolor sit amet, consectetur [23] adipiscing elit. Phasellus quis lectus metus, at posuere neque. Sed pharetra nibh [24] eget orci convallis at posuere leo convallis. Sed blandit augue [25] vitae augue scelerisque bibendum. Vivamus sit amet libero turpis, non venenatis urna. In blandit, odio convallis suscipit venenatis, ante ipsum cursus [26] augue.';
$searchStrings = [
                  '[23]',
                  '[24]',
                  '[25]',
                  '[26]',
                 ];
$replacements  = [
                  '[foo]',
                  '[bar]',
                  '[baz]',
                  '[quix]',
                 ];
$newText = str_replace($searchStrings, $replacements, $fulltext);

Which gives you

"Lorem ipsum dolor sit amet, consectetur [foo] adipiscing elit. Phasellus quis lectus metus, at posuere neque. Sed pharetra nibh [bar] eget orci convallis at posuere leo convallis. Sed blandit augue [baz] vitae augue scelerisque bibendum. Vivamus sit amet libero turpis, non venenatis urna. In blandit, odio convallis suscipit venenatis, ante ipsum cursus [quix] augue."

2 Comments

preg_replace('/\[\d*\]+/', $replacement, $fulltext); is also wrong... that will match any number of closing brackets
You're right. I have no idea how the + slipped in there. Fixed, thanks :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.