开发者

Regex expression in plain english

开发者 https://www.devze.com 2022-12-30 01:06 出处:网络
I\'m working on a new Java project and therefore im reading the already existing code. On a very important part of the code if开发者_运维百科 found the following regex expression and i can\'t really t

I'm working on a new Java project and therefore im reading the already existing code. On a very important part of the code if开发者_运维百科 found the following regex expression and i can't really tell what they are doing. Anybody can explain in plain english what they do??

1)

 [^,]*|.+(,).+

2)

(\()?\d+(?(1)\))


Next time you need a regex explained, you can use the following explain.pl service from Rick Measham:

Regex: [^,]*|.+(,).+

NODE                     EXPLANATION
--------------------------------------------------------------------------------
  [^,]*                    any character except: ',' (0 or more times
                           (matching the most amount possible))
--------------------------------------------------------------------------------
 |                        OR
--------------------------------------------------------------------------------
  .+                       any character except \n (1 or more times
                           (matching the most amount possible))
--------------------------------------------------------------------------------
  (                        group and capture to \1:
--------------------------------------------------------------------------------
    ,                        ','
--------------------------------------------------------------------------------
  )                        end of \1
--------------------------------------------------------------------------------
  .+                       any character except \n (1 or more times
                           (matching the most amount possible))

Regex: (\()?\d+(?(1)\))

NODE                     EXPLANATION
--------------------------------------------------------------------------------
  (                        group and capture to \1 (optional
                           (matching the most amount possible)):
--------------------------------------------------------------------------------
    \(                       '('
--------------------------------------------------------------------------------
  )?                       end of \1 (NOTE: because you're using a
                           quantifier on this capture, only the LAST
                           repetition of the captured pattern will be
                           stored in \1)
--------------------------------------------------------------------------------
  \d+                      digits (0-9) (1 or more times (matching
                           the most amount possible))
--------------------------------------------------------------------------------
  (?(1)                    if back-reference \1 matched, then:
--------------------------------------------------------------------------------
    \)                       ')'
--------------------------------------------------------------------------------
   |                        else:
--------------------------------------------------------------------------------
                             succeed
--------------------------------------------------------------------------------
  )                        end of conditional on \1

Links

  • http://rick.measham.id.au/paste/explain.pl

Note on conditionals

JAVA DOES NOT SUPPORT CONDITIONALS! An unconditionalized regex for the second pattern would be something like:

\d+|\(\d+\)

i.e. a non-zero repetition of digits, with or without surrounding parentheses.

Links

  • regular-expressions.info/If-then-else conditionals

    Conditionals are supported by the JGsoft engine, Perl, PCRE and the .NET framework.


The patterns in depth

Here's a test harness for the first pattern

    import java.util.regex.*;
    //...

    Pattern p = Pattern.compile("[^,]*|.+(,).+");
    String[] tests = {
        "",       // [] is a match with no commas
        "abc",    // [abc] is a match with no commas
        ",abc",   // [,abc] is not a match
        "abc,",   // [abc,] is not a match
        "ab,c",   // [ab,c] is a match with separating comma
        "ab,c,",  // [ab,c,] is a match with separating comma
        ",",      // [,] is not a match
        ",,",     // [,,] is not a match
        ",,,",    // [,,,] is a match with separating comma
    };
    for (String test : tests) {
        Matcher m = p.matcher(test);
        System.out.format("[%s] is %s %n", test,
            !m.matches() ? "not a match"
            : m.group(1) != null
               ? "a match with separating comma"
               : "a match with no commas"
        );
    }

Conclusion

  • To match, the string must fall into one of these two cases:
    • Contains no comma (potentially an empty string)
    • Contains a comma that separates two non-empty strings
  • On a match, \1 can be used to distinguish between the two cases

And here's a similar test harness for the second pattern, rewritten without using conditionals (which isn't supported by Java):

    Pattern p = Pattern.compile("\\d+|(\\()\\d+\\)");
    String[] tests = {
        "",       // [] is not a match
        "0",      // [0] is a match without parenthesis
        "(0)",    // [(0)] is a match with surrounding parenthesis
        "007",    // [007] is a match without parenthesis
        "(007)",  // [(007)] is a match with surrounding parenthesis
        "(007",   // [(007] is not a match
        "007)",   // [007)] is not a match
        "-1",     // [-1] is not a match
    };
    for (String test : tests) {
        Matcher m = p.matcher(test);
        System.out.format("[%s] is %s %n", test,
            !m.matches() ? "not a match"
            : m.group(1) != null
               ? "a match with surrounding parenthesis"
               : "a match without parenthesis"
        );
    }

As previously said, this matches a non-zero number of digits, possibly surrounded by parenthesis (and \1 distinguishes between the two).


1)

[^,]* means any number of characters that are not a comma
.+(,).+ means 1 or more characters followed by a comma followed by 1 or more characters
|  means either the first one or the second one

2)

(\()? means zero or one '('  note* backslash is to escape '('
\d+ means 1 or more digits
(?(1)\)) means if back-reference \1 matched, then ')' note* no else is given

Also note that parenthesis are used to capture certain parts of the regular expression, except, of course, if they are escaped with a backslash


1) Anything that doesn't starts with a comma, or anything that contains a comma in between.

2) Any number that ends with a 1, and is between parenthesis, possible closed before and opened again after the number.

0

精彩评论

暂无评论...
验证码 换一张
取 消