Long Regex - 你会怎么做?

时间:2009-07-31 20:26:57

标签: c# regex

嘿伙计们,我有一个很长的正则表达式,很难看。 我想知道你是否可以帮助缩短它,所以它更易于管理。 我承认,我不是一个正则表达的大师,我只是躲开了。如果你想出更好的东西(它甚至不需要更短),请解释你的推理,这样我就可以更好地理解你使用的技术。

正则表达式:

^([a-zA-Z0-9# ]+)-([a-zA-Z ]*)([a-zA-Z0-9_ ]+)-([a-zA-Z0-9_ ]+)-([a-zA-Z0-9_ ]+)-([a-zA-Z0-9_ ]+)-([a-zA-Z0-9_ ]+)-([a-zA-Z0-9_ ]+)-([a-zA-Z0-9_ ]+)-([a-zA-Z0-9_ ]+)-([a-zA-Z0-9_ ]+)-([a-zA-Z ~]+)([a-zA-Z0-9_ ]+)\.rpt$

试验:

TESTFIX - ABCD 10118 - E008 - E009 - IXX - IXX - IXX - IXX - IXX - IXX - SX ~ 91.rpt
TESTFIX - EFGD 10118 - E008 - E009 - IXX - IXX - IXX - IXX - IXX - IXX - SX ~ 92.rpt
TESTFIX - 10118_14041 M - E008 - E009 - IXX - IXX - IXX - IXX - IXX - IXX - SX ~ 93.rpt
TESTFIX - ABCD 10118 - E008 - E009 - IXX - IXX - IXX - IXX - IXX - IXX - SX ~ 93.rpt
TESTFIX - EFGD 10118 - E008 - E009 - IXX - IXX - IXX - IXX - IXX - IXX - SX ~ 93.rpt
TESTFIX - EFGD 10118 - E008 - E009 - IXX - IXX - IXX - IXX - IXX - IXX - SX ~ 93.rpt
TESTFIX - ABCD 10118 - E008 - E009 - IXX - IXX - IXX - IXX - IXX - IXX - SX ~ 93.rpt
#1REALLYLONGNAME - 10244 - E011 - E009 - IXX - IXX - IXX - IXX - IXX - IXX - DX ~ ALPHALTR.rpt
#1 LIVEREP - 10045 - E011 - E009 - IXX - IXX - IXX - IXX - IXX - IXX - SX ~ SING.rpt
#2 LIVEREP - 10045 M - E011 - E009 - IXX - IXX - IXX - IXX - IXX - IXX - SX ~ MUL.rpt
WELLREP - WELL10000 - E011 - E009 - IXX - IXX - IXX - IXX - IXX - IXX - SX ~ CLT.rpt

每个部分由' - '字符序列分开。 所有部分都可以包含空格和任何有效的文件名字符

必须为每个部分进行群组捕获 如果重要的话,我将在C#

中使用这个正则表达式

3 个答案:

答案 0 :(得分:5)

首先,获得一个很好的正则表达式开发工具。我最喜欢的是Expresso

这是一个清理版本:

^[\w# ]+ - [a-zA-Z ]*(?:[\w_ ]+ - ){9}[a-zA-Z]+ ~[\w_ ]+\.rpt$

更改包括:

  • 删除了捕获分组“()” - 我会假设你只是 验证文本,因为你没有 提到任何捕获。如果你需要 他们,他们很容易加回来
  • 使用字母数字字符类 - “\ w”,相当于“[a-zA-Z0-9]”
  • 用“(?:[\ w_] + - ){9}”替换中间的重复部分“这匹配([字母数字下划线空格] + - )9次。它没有被捕获,因为我在第一个括号之后放了“?:”。

编辑:

这里是捕获组的回复:

^([\w# ]+) - ([a-zA-Z ]*)(?:([\w_ ]+) - ){9}([a-zA-Z]+) ~ ([\w_ ]+)\.rpt$

请注意,当您浏览编号的捕获组时,第三个捕获组将包含9个捕获。

答案 1 :(得分:4)

当你在谈论“简化”正则表达式时,你真的需要知道你想要匹配的内容,因为这可以真正帮助简化你的特殊字符测试,重复序列等等。

那就是说,这是一个清理版本,它产生的与原始表达式完全相同

^([a-zA-Z0-9# ]+)-([a-zA-Z ]*)(?:([\w ]+)-){9}([a-zA-Z ~]+)([\w ]+)\.rpt$

有关为何与其他答案不同的一些说明:

  • 根据我对Perl兼容正则表达式的引用,\ w实际上还包括下划线。 (编辑:这显然与C#不同,后者在MSDN链接中有说明。这种差异可能会有用。)
  • 我的表达式假设您有意在字符类中使用空格。事实上,如果你可以在短划线之间有多个空格,请保持这种方式,否则,请选择其他答案。

答案 2 :(得分:3)

您可以用\ w替换a-zA-Z0-9_的每个实例。此外,0-9可以稍微缩短为\ d。

以下是C#支持的字符类: http://msdn.microsoft.com/en-us/library/20bw873z%28VS.71%29.aspx

您可以通过在组的左括号之后的开头包含?:来使组成为非捕获组。如果您的表达式重复已知次数,则可以使用{n}:

进行跟踪

^([a-zA-Z\d# ]+)-([a-zA-Z ]*)(?:([\w ]+)-){9}([a-zA-Z ~]+)([\w ]+)\.rpt$