Попытка создать RegEx для следующих шаблонов - PullRequest
0 голосов
/ 25 декабря 2010

Вот шаблоны:

Red,Green (and so on...)
Red (+5.00),Green (+6.00) (and so on...)
Red (+5.00,+10.00),Green (+6.00,+20.00) (and so on...)
Red (+5.00),Green  (and so on...)

Каждый атрибут («Красный, Зеленый») может иметь модификаторы 0, 1 или 2 (отображаются как «+ 5.00, + 10.00» и т. Д.).

Мне нужно захватить каждый из атрибутов и их модификаторов в виде одной строки (т. Е. «Красный (+ 5,00, + 10,00)», «Зеленый (+ 6,00, + 20,00)».

Помощь

Ответы [ 3 ]

1 голос
/ 25 декабря 2010

Другой пример (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)
        )

)

Может быть, есть более простое регулярное выражение, я неэксперт ...

0 голосов
/ 25 декабря 2010

Вот моя ставка:

/
  (?:^|,)                   # Match line beginning or a comma
  (?:                       # parent wrapper to catch multiple "color (+#.##)" patterns
    (                         # grouping pattern for picking off matches
      (?:(?:Red|Green),?)+      # match the color prefix
      \s\(                      # space then parenthesis
      (?:                       # wrapper for repeated number groups
        (?:\x2B\d+\.\d+)          # pattern for the +#.##
      ,?)+                      # end wrapper
      \)                        # closing parenthesis
    )+                        # end matching pattern
  )+                        # end parent wrapper
/

Что означает:

/(?:^|,)(?:((?:(?:Red|Green),?)+\s\((?:(?:\x2B\d+\.\d+),?)+\))+)+/

РЕДАКТИРОВАТЬ

Извините, это был только последнийшаблон до.Это поймает все совпадения (или должны).

0 голосов
/ 25 декабря 2010

формат PCRE:

(Red|Green)(\s\((?P<val1>.+?)(,){0,1}(?P<val2>.+?){0,1}\)){0,1}

Матч из PHP:

preg_match_all("/(Red|Green)(\s\((?P<val1>.+?)(,){0,1}(?P<val2>.+?){0,1}\)){0,1}/ims", $text, $matches);
...