尝试为以下模式创建RegEx

时间:2010-12-25 15:49:36

标签: regex pcre

以下是模式:

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”等)。

我需要将每个属性及其修饰符捕获为单个字符串(即“Red(+ 5.00,+ 10.00)”,“Green(+ 6.00,+ 20.00)”。

帮助?

3 个答案:

答案 0 :(得分:1)

另一个例子(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)
        )

)

也许有一个更简单的正则表达式,我不是专家......

答案 1 :(得分:0)

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);

答案 2 :(得分:0)

这是我的出价:

/
  (?:^|,)                   # 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+),?)+\))+)+/

修改

对不起,它之前只捕获了最后一个模式。这将捕获所有匹配(或应该)。