2009-08-26 66 views
2

考虑一个字符串,它看起来像这样:C#:判断字符串是否像这种模式;可能正则表达式

RR1 S5 C92

这是一个农村的路线地址外的镇邮件投递:农村路线,站点,车厢。每个字母后跟一个数字和一个空格。通常一到三位数字,但你永远不知道它可能有多少个数字!如果用户懒惰,他们可能输入了零个,一个或多个空格。

问题: 您将使用什么正则表达式来确定给定的字符串是否与此模式匹配?

它的用法是这样的:

string ruralPattern; //a regex pattern here 
bool isRural = Regex.Match(someString, ruralPattern); 

更新:谢谢您的建议!性能和使用将在一个静态方法中从一个Web服务调用。根据此模式检查的字符串将最多为50个字符。该方法将大约每5秒调用一次。任何建议保持静态?非常感激!

回答

9

这应该工作:

^[Rr][Rr]\d+ *[Ss]\d+ *[Cc]\d+$ 

或按其他评论

^[Rr][Rr][0-9]+ *[Ss][0-9]+ *[Cc][0-9]+$ 

这一切意味着什么:

  • ^- 串
  • 开始
  • [RR] - 下一个字符必须是R或r
  • [RR] - 下一个字符必须是R或R
  • \ d +或[0-9] + - 下一部分必须是1个或多个数字
  • (空格)* - 允许0或多个空格
  • [SS] - 下一个字符必须是S或S
  • \ d +或[0-9] + - 下一部分必须是1个或多个数字
  • (空格)* - 允许0或多个空格
  • [Cc] - 下一个字符必须是C或c
  • \ d +或[0-9] + - 下一部分必须是1或多个数字
  • $ - 字符串结尾

可能有一个更优雅的解决方案,但是这很容易阅读。

编辑:更新,包括一些评论

+0

简单性对于正则表达式来说是件好事。 – 2009-08-26 22:26:58

+0

肯定......我希望更多的人会分解他们的解决方案,因为我已经在上面让他们更容易理解,因为正则表达式不是最易读的语法。 – Kelsey 2009-08-26 22:36:50

+0

@凯尔西:感谢您解释正则表达式语法 – escist 2013-03-20 13:56:10

3

的输入......怎么

someString = someString.Trim(); // eliminate leading/trailing whitespace 
bool isRural = Regex.Match(
    someString, 
    @"^rr\d+\s*s\d+\s*c\d+$", 
    RegexOptions.IgnoreCase); 

这消除了在图案内大/小写切换,并使用\s允许任何(非换行符)空白字符(例如制表符)。如果您只需要空格,则应将'\s'更改为' '

+1

+1,这是最简单也是最正确的答案,但**,请注意'\ d'不仅仅匹配'[0-9]'。它匹配char.IsDigit返回true的任何字符,在我的计数中包含一些** 230 ** unicode代码点。 – 2009-08-27 01:14:03

+0

是的,的确如此,并且可以对'\ s'('char.IsWhiteSpace')进行类似的声明。 – bobbymcr 2009-08-27 03:23:20

+0

@P - 感谢您对“\ d”的洞察! – 2009-08-27 15:25:03

1

让我们澄清如下推定:

  1. 有三个部分的字符串。
  2. 第1部分始终以RR大写或小写开头,并以一个或多个小数位结尾。
  3. 第2节始终以S大写或小写开头,并以一位或多位小数位结尾。
  4. 第3节总是以C开头或以下,并以一位或多位小数位结尾。

为简单起见,以下内容就足够了。

[Rr][Rr][0-9]+[ ]+[Ss][0-9]+[ ]+[Cc][0-9]+ 
  1. [RR]指恰好一个字母R, 大写或小写。
  2. [0-9]意味着精确的一位小数点 数字。
  3. [0-9] +表示至少一个或多个 的十进制数字。
  4. [] +表示至少有一个或多个 空格。

但是,通常,当您使用正则表达式时,我们还会检测各个部分以利用匹配功能来帮助我们将各个部分值分配给它们各自的/单独的变量。

因此,下面的正则表达式更有帮助。

([Rr][Rr][0-9]+)[ ]+([Ss][0-9]+)[ ]+([Cc][0-9]+) 

让该正则表达式应用于字符串

string inputstr = "Holy Cow RR12 S53 C21"; 

这是你的正则表达式匹配将让你知道:

start pos=9, end pos=21 
Group(0) = Rr12 S53 C21 
Group(1) = Rr12 
Group(2) = S53 
Group(3) = C21 

有三对椭圆/圆括弧的。 每对是正则表达式编译器调用组的一部分字符串。

正则表达式编译器将调用

  1. 比赛整个匹配的字符串为0组
  2. 农村的路线为1组
  3. 网站作为第2组和
  4. 货舱中组3

当然,组1,3将遇到匹配,当且仅当组0具有匹配。

因此,你的算法会利用与下面的伪代码

string postalstr, rroute, site, compart; 
if (match.group(0)!=null) 
{ 
    int start = match.start(0); 
    int end = match.end(0); 
    postalstr = inputstr.substring(start, end); 

    start = match.start(1); 
    end = match.end(1); 
    rroute = inputstr.substring(start, end); 

    start = match.start(2); 
    end = match.end(2); 
    site = inputstr.substring(start, end); 

    start = match.start(3); 
    end = match.end(3); 
    compart = inputstr.substring(start, end); 
} 

此外,你可能要进入与列的数据库表:RR,网站,舱室,但你只想要数字输入没有字母“rr”,“s”或“c”。 这将是使用嵌套分组的正则表达式。

([Rr][Rr]([0-9]+))[ ]+([Ss]([0-9]+))[ ]+([Cc]([0-9]+)) 

而且匹配会让你知道什么时候发生匹配组0以下:

start=9, end=21 
Group(0) = Rr12 S53 C21 
Group(1) = Rr12 
Group(2) = 12 
Group(3) = S53 
Group(4) = 53 
Group(5) = C21 
Group(6) = 21 
0

FYI:如果你要使用这个正则表达式来测试大量的数据,你最好的选择就是告诉.NET预编译它 - 它将被编译成IL并提供性能提升,而不是每次都简单地解释RegEx模式。指定为上哪个类包含你的方法静态成员,像这样:

private static Regex re = new Regex("pattern", RegexOptions.Compiled | RegexOptions.IgnoreCase); 

...和方法来测试一个字符串是否匹配模式是...

bool matchesString = re.IsMatch("string"); 

好运。

+1

*可能*。 'RegexOptions.Compiled'并不总是一个胜利,并且分析是必要的。参见:http://www.codinghorror.com/blog/archives/000228.html和http://stackoverflow.com/questions/414328/using-static-regex-ismatch-vs-creating-an-instance-of-正则表达式/ 414411#414411 – 2009-08-27 02:35:20

+0

谢谢Tullo和PDaddy。围绕预期用法的问题更新! – 2009-08-27 03:38:35

相关问题