PHP Regex with parentheses

2020-04-14 07:10发布

I have the below string:

test 13 (8) end 12 (14:48 IN 1ST)

I need the output to be:

14:48 IN 1ST

or everything inside parentheses towards the end of the string.

I don't need, 8 which is inside first set of parentheses. There can be multiple sets of parentheses in the string. I only need to consider everything inside the last set of parentheses of input string.

标签: php regex
6条回答
闹够了就滚
2楼-- · 2020-04-14 07:10

This regex will do: .+\((.+?)\)$

Escape the parentheses, make the + non-greedy with ?, and make sure it's at the end of the line.

If there may be characters after it, try this instead:

.\).+\((.+?)\)

Which basically makes sure only the second parentheses will match. I would still prefer the first.

查看更多
贪生不怕死
3楼-- · 2020-04-14 07:11

I would go with the following regex:

.*\(([^)]+)\)
查看更多
淡お忘
4楼-- · 2020-04-14 07:17

I wouldn't use a regex for this, it's unnecessary.

Use strrpos and substr to extract the string that you need. It's simple, straightforward, and achieves the desired output.

It works by finding the last '(' in the string, and removing one character from the end of the string.

$str = "test 13 (8) end 12 (14:48 IN 1ST)";
echo substr( $str, strrpos( $str, '(')  + 1, -1);

$str = "(dont want to capture the (8)) test 13 (8) end 12 (14:48 IN 1ST)";
echo substr( $str, strrpos( $str, '(')  + 1, -1);

Demo

Edit: I should also note that my solution will work for all of the following cases:

  1. Empty parenthesis
  2. One set of parenthesis (i.e. the string before the desired grouping does not contain parenthesis)
  3. More than three sets of parenthesis (as long as the desired grouping is located at the end of the string)
  4. Any text following the last parenthesis grouping (per the edits below)

Final edit: Again, I cannot emphasis enough that using a regex for this is unnecessary. Here's an example showing that string manipulation is 3x - 7x faster than using a regex.

As per MetaEd's comments, my example / code can easily be modified to ignore text after the last parenthesis.

$str = "test 13 (8) end 12 (14:48 IN 1ST) fkjdsafjdsa";
$beginning = substr( $str, strrpos( $str, '(')  + 1);
substr( $beginning, 0, strpos( $beginning, ')')) . "\n";

STILL faster than a regex.

查看更多
家丑人穷心不美
5楼-- · 2020-04-14 07:22

Regex Explanation

.*       Go to last
\(       Stars with (
([^)]*) 0 or more character except )
\)       Ends with 

preg_match

$str = "test 13 (8) end 12 () (14:48 IN 1ST) asd";
$regex = "/.*\(([^)]*)\)/";
preg_match($regex,$str,$matches);

$matches
array (
  0 => 'test 13 (8) end 12 () (14:48 IN 1ST)',
  1 => '14:48 IN 1ST',
)

Accept Empty preg_match_all

$str = "test 13 (8) end 12 () (14:48 IN 1ST) asd";
$regex = "/\(([^)]*)\)/";

preg_match_all($regex,$str,$matches);

$matches
array (
  0 => 
  array (
    0 => '(8)',
    1 => '()',
    2 => '(14:48 IN 1ST)',
  ),
  1 => 
  array (
    0 => '8',
    1 => '',
    2 => '14:48 IN 1ST',
  ),
)

Don't Accept Empty preg_match_all

$str = "test 13 (8) end 12 () (14:48 IN 1ST) asd";
$regex = "/\(([^)]+)\)/";

preg_match_all($regex,$str,$matches);

$matches
array (
  0 => 
  array (
    0 => '(8)',
    1 => '(14:48 IN 1ST)',
  ),
  1 => 
  array (
    0 => '8',
    1 => '14:48 IN 1ST',
  ),
)
查看更多
The star\"
6楼-- · 2020-04-14 07:34

\(.*\) will match the first and last parens. To prevent that, begin with .* which will greedily consume everything up to the final open paren. Then put a capture group around what you want to output, and you have:

.*\((.*)\)
查看更多
成全新的幸福
7楼-- · 2020-04-14 07:35

The easiest thing would be to split the string on ')' and then just grab everything from the last item in the resulting array up till '('... I know it's not strictly regex but it's close enough.

[edit] (to make sure people who love to down-vote things before actually understanding what's being said... (like JV), can have actual code to consider)...

"test 13 (8) end 12 (14:48 IN 1ST)".split( /)/);

This will produce an array with two elements... "test 13 (8" and " end 12 (14:48 IN 1ST"

Notice that no matter how many (xyz) you have in there you will end up with the last one in the last array item.

Then you just look through that last item for a '(' and if it's there grab everything behind it.

I suspect this will work faster than a straight regex approach, but I haven't tested, so can't guarantee that... regardless it does work. [/edit]

查看更多
登录 后发表回答