【问题标题】:How to simplify the following regex如何简化以下正则表达式
【发布时间】:2013-06-04 11:59:50
【问题描述】:

我正在尝试匹配代表维度的模式:

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

数字可以是 double(使用点或逗号)或 int。分隔符可以是 xX*/\(并且可以混合为,例如:5*3x9)。维度中最多有 3 个数字,第 3 个数字不是强制性的(我通常只匹配 2 个维度)。数字和分隔符之间可以有任意数量的空格。我正在使用这个运行良好的正则表达式,但我想知道是否有更简单的方法来实现它:

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

【问题讨论】:

  • 您可以使用以下regex
  • 为什么必须是一个正则表达式?你可以把它分成 4 个不同的,每个都比你拥有的简单得多。
  • 不错的网站,但具有讽刺意味的是,网络使用正则表达式来搜索正则表达式模式来描述正则表达式语法
  • @Oded 我不明白你的意思,我需要在字符串中匹配这个模式,所以我需要一个完整的正则表达式来捕获那些特定的组
  • 我不会使用正则表达式,以使代码更具可读性:首先使用 String.Split() 进行传递以获取数字。然后使用 String.IndexOfAny() 执行一(或两次)传递以获取分隔符。

标签: c# regex simplify


【解决方案1】:

你可以使用量词{1,2},表示匹配一到两次。最后一个可选组与正则表达式中间的过去相同。所以只需删除重复的部分并在组上使用该量词。

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

看到它here on Regexr。我添加了锚点^$,这取决于您在.net 中使用的方法是否需要它们。

【讨论】:

  • 这不会这样做,因为匹配两次这与匹配具有 3 个数字的模式不同:此版本不允许 3*3*3。
  • @C4stor 检查正则表达式链接。当然是匹配“3*3*3”。我刚刚删除了最后一个可选部分。
  • 嗯,这实际上很有用,没有想到量词,我正在测试这个,谢谢
【解决方案2】:

我发布了一个之前的答案,其中我误读了您的部分问题。所以这是重做。

老实说,这是最好的正则表达式:

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

为什么?因为使用此语句,您有一个 Group 1、Group 2 和 Group 3,您可以从中提取三个值(显然,第三个有时可能是空白的)。如果你使用量词重复一个子表达式,你将不得不进入组集合,你的代码会变得混乱。

我的长款和你的长款有什么区别?好吧,上面的 long 可以更好地处理“小数”,而您的则允许不正确的数字,例如“382”。

但如果您想要走的路线更短,那么正则表达式将是:

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

在这种情况下,您的代码可以从第 1 组中提取第一个值,但随后必须使用组集合来查看第 2 组是否有堆栈或只有一个值。如果是堆栈,则获取值 2 的捕获集合项 0,然后获取值 3 的捕获集合项 1。

这些正则表达式与 Stema 的非常相似,除了它们组织捕获组。

故障:

(              //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

同样,我的“简短”答案与 Stema 的不同之处在于,我的答案更恰当地处理了“小数”。但是您可能不需要额外的安全性,在这种情况下,stema 就可以了。此外,当您只是使用子表达式进行分组或重复时,使用非捕获表达式,并且不想捕获它。从长远来看,向这些堆栈添加值确实会影响您的处理速度。

因此,如果您不关心捕获组、处理完美或正确的小数处理......而您想要的只是尽可能短的正则表达式,Stema 就一针见血。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多