Другой пример (PCRE):
((?:Red|Green)(?:\s\((?:\+\d+\.\d+,?)+\))?)
Объяснение:
(...) // a capture group
(?:...) // a non-capturing group
Read|Green // matches Red or Green
(?:...)? // an optional non-capturing group
\s // matches any whitespace character
\( // matches a literal (
(?:...)+ // a non-capturing group that can occur one or more times
\+ // matches a literal +
\d+ // matches one or more digits
\. // matches a literal .
\d+ // matches one or more digits
,? // matches an optional comma
\) //matches a literal )
Обновление:
Или фактически, если вы просто хотите извлечь данные, тогда
((?:Red|Green)(?:\s\([^)]+\))?)
будет достаточно.
Обновление 2: Как указано в вашем комментарии, это будет соответствовать чему-либо в первой части, кроме ,
и (
:
([^,(]+(?:\s\([^)]+\))?)
(не работает, слишком разрешительно)
, чтобы быть более ограничительным (допускаются только символы и цифры,Вы можете просто использовать \w
:
(\w+(?:\s\([^)]+\))?)
Обновление 3 :
Я вижу, первая из моих альтернатив не работает правильно, но \w
работает:
$pattern = "#\w+(?:\s\([^)]+\))?#";
$str = "foo (+15.00,-10.00),bar (-10.00,+25),baz,bing,bam (150.00,-5000.00)";
$matches = array();
preg_match_all($pattern, $str, $matches);
print_r($matches);
отпечатки
Array
(
[0] => Array
(
[0] => foo (+15.00,-10.00)
[1] => bar (-10.00,+25)
[2] => baz
[3] => bing
[4] => bam (150.00,-5000.00)
)
)
Обновление 4:
Хорошо, у меня что-то работает, пожалуйста, проверьтевсегда ли это работает:
(?=[^-+,.]+)[^(),]+(?:\s?\((?:[-+\d.]+,?)+\))?
С:
$pattern = "#(?=[^-+,.]+)[^(),]+(?:\s?\((?:[-+\d.]+,?)+\))?#";
$str = "5 lb. (+15.00,-10.00),bar (-10.00,+25),baz,bing,bam (150.00,-5000.00)";
preg_match_all
дает мне
Array
(
[0] => Array
(
[0] => 5 lb. (+15.00,-10.00)
[1] => bar (-10.00,+25)
[2] => baz
[3] => bing
[4] => bam (150.00,-5000.00)
)
)
Может быть, есть более простое регулярное выражение, я неэксперт ...