I'm trying to match pattern that represent dimension like :

2,2x3
3*5
4  X 44,5
5x5x5

Numbers can be either double (using dot or comma) or int. Separator can either be xX*/\ (and can be mixed to, like: 5*3x9). There is a maximum of 3 numbers in the dimension and the 3rd one is not mandatory (i often match only 2 dimension). There can be any number of space between number and separator. Im using this regexp which is working quiet fine but i wondered if there would be any easier way of achieving it :

(\d+[.,]?\d*)\s*[xX*/\\]\s*(\d+[.,]?\d*)(\s*[xX*/\\]\s*(\d+[.,]?\d*))?
有帮助吗?

解决方案 2

I posted a previous answer where I had misread part of your question. So this is a re-do.

In all honesty, this is the best Regex Statement:

(\d+(?:[.,]\d+)?)\s*[xX*/\\]\s*(\d+(?:[.,]\d+)?)(?:\s*[xX*/\\]\s*(\d+(?:[.,]\d+)?))?

Why? Because with this statement, you have a Group 1, Group 2, and Group 3 from which you can pull your three values (The third may sometimes be blank, obviously). If you use quantifiers to repeat a sub-expression, you would have to get into group collections and your code would get messy.

What's the difference between my long one, and your long one? Well, the long one above has better handling for "decimals", whereas yours would allow improper numbers such as "382.".

But if shorter is the route you want to take, the Regex would be:

(\d+(?:[.,]\d+)?)(?:\s*[xX*/\\]\s*(\d+(?:[.,]\d+)?)){1,2}

In this case, your code could pull the first value from Group 1, but then would have to use a group collection to see if Group 2 has a stack or just a single value. If it's a stack, get capture collection item 0 for value 2, then capture collection item 1 for value 3.

These regexes are very simlar to Stema's, except they organize capture groups.

The Breakdown:

(              //Capture Group 1 - Begin
  \d+          //Require Digits
  (?:          //Non Capture Sub Expression
    [.,]\d+    //Allow a "Decimal", but if it exists, Require Digits after it
  )?           //Optional Quantifier for the "decimal" sub-expression
)              //Capture Group 1 - End
(?:            //Non Capture Sub Expression
  \s*          //Optionally capture space(s)
  [xX*/\\]     //Require a Separator
  \s*          //Optional capture space(s)
  (            //Capture Group 2 - Begin
    \d+        //Require Digits
    (?:        //Non Capture Sub Expression
      [.,]\d+  //Allow a "Decimal", but if it exists, Require Digits after it
    )?         //Optional Quantifier for the "decimal" sub-expression
  )            //Capture Group 2 - End
){1,2}         //Require at least one Separator/Digit pattern, but allow two

Again, the difference between my "short" answer and Stema's, is just that mine handles "Decimals" more appropriately. But you may not require that extra security, in which case stema's is fine. Also, use non-capture expressions when you are just using a sub-expression for grouping or repetition, and don't want to capture it. In the long run, adding values to those stacks does weigh a little on your processing speed.

So if you don't care about capture groups, processing perfection, or proper decimal handling... and all you want is the shortest possible regex, Stema hit the nail on the head.

其他提示

You can use the quantifier {1,2}, means match one or two times. The last optional group is the same than the past in the middle of your regex. so just remove the duplicated part and use that quantifier on the group.

(\d+[.,]?\d*)(\s*[xX*/\\]\s*(\d+[.,]?\d*)){1,2}

See it here on Regexr. I added the anchors ^ and $, depends on the method you use in .net if you need them or not.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top