2009-08-05 158 views
5

我正在使用Ruby的scan()方法来查找特定格式的文本。然后我将它输出到一个由逗号分隔的字符串中。我试图找到看起来像这样的文字:ruby​​正则表达式.scan

AB_ABCD_123456

这里是我想出来的,到目前为止,发现上面。它工作正常:

text.scan(/.._...._[0-9][0-9][0-9][0-9][0-9][0-9]/) 
puts text.uniq.sort.join(', ') 

现在我需要一个正则表达式会发现上面有或没有在最后一两个字母的国家名称。例如,我希望能够找到所有三个如下:

AB_ABCD_123456
AB_ABCD_123456UK
AB_ABCD_123456DE

我知道我可以使用两种或三种不同的扫描来实现我的结果,但我m想知道是否有一种方法可以用一个正则表达式来获得所有三种方法。

回答

12
/.._...._[0-9][0-9][0-9][0-9][0-9][0-9](?:[A-Z][A-Z])?/ 

您还可以使用{},使正则表达式更短:

/.{2}_.{4}_[0-9]{6}(?:[A-Z]{2})?/ 

说明:?,使前面的模式可选。 ()将表达式组合在一起(所以红宝石知道?适用于这两个字母)。开放(后的?:使得该组未捕捉(捕捉组将改变由扫描产生的值)。

+0

效果很好,谢谢,快捷键会有所帮助。 – michaelmichael 2009-08-05 21:34:15

1
/.._...._\d{6}([A-Z]{2})?/ 
+1

如果您没有进行组非捕获扫描将只会产生国家代码(或零为不包括一个字符串),而不是整个匹配的字符串。 – sepp2k 2009-08-05 21:24:09

1

为什么不直接使用split?

"AB_ABCD_123456".split(/_/).join(',') 

处理您未经修改列出的情况。

+0

AFAIK,OP正试图找到这些代码的列表......不能只用一个。 – 2009-08-05 21:58:54

+1

是的;我看到了这个例子,跳过了细节 - 一个可怕的习惯。对困惑感到抱歉。 – ezpz 2009-08-05 23:50:27

1

试试这个:

text.scan(/\w{2}_\w{4}_\d{6}\w{0,2}/) 
#matches AB_ABCD_123456UK or ab_abcd_123456uk and so on... 

text.scan(/[A-Z]{2}_[A-Z]{4}_\d{6}[A-Z]{0,2}/) 
# tighter, matches only AB_ABCD_123456UK and similars... 
# and not something like ab_aBCd_123456UK or ab_abcd_123456uk and similars... 

参阅以下网址:

Ruby gsub/regex modifiers?

http://ruby-doc.org/docs/ruby-doc-bundle/Manual/man-1.4/syntax.html#regexp

如果你想了解更多关于正则表达式。

+0

我喜欢那个第二个正则表达式的例子。感谢您的链接。我已经经历过他们,尽管不尽如人意。真实的生活问题帮助我理解了很多。 – michaelmichael 2009-08-05 22:01:02