我有一堆电话号码,每行一个:
[Home] (202) 121-7777
C (202) 456-1111
[mobile] 55 55 5 55555
[Work] (404) 555-1234
[Cell] (505) 555-1234
W 303-555-5555
M 777-555-5555
c 12346567s
我想抓住包含字母“c”大写或小写的第一个。
到目前为止,我有/^.*[C].*$/i
这个匹配C (202) 456-1111
,[Cell] (505) 555-1234
和c 12346567s
。我如何只返回第一个?换句话说,匹配应该只是C (202) 456-1111
。
我盲目地question marks everywhere没有成功。
我正在使用Ruby,如果它有所作为http://www.rubular.com/r/h6ReB9IN8t
编辑:这是Hrishi指出的another question,但我无法弄清楚如何调整它以匹配整条线。
答案 0 :(得分:2)
尝试match
方法。这是一个例子:
list = <<EOF
[Home] (202) 121-7777
C (202) 456-1111
[mobile] 55 55 5 55555
[Work] (404) 555-1234
[Cell] (505) 555-1234
W 303-555-5555
M 777-555-5555
c 12346567s
EOF
<强>更新强>
#match line with "c" letter in line, even that are part of word
puts list.match(/^.*C.*$/i)
#match line with "c" letter in line, that are not a part of word
puts list.match(/^\W*C\W.*$/i)
答案 1 :(得分:1)
按新行字符拆分字符串,select
符合您要求的子字符串并抓取第一个字符串:
str = '[Home] (202) 121-7777
C (202) 456-1111
[mobile] 55 55 5 55555
[Work] (404) 555-1234
[Cell] (505) 555-1234
W 303-555-5555
M 777-555-5555
c 12346567s'
p str.split(/\n/).select{|el| el =~ /^.*[C].*$/i}[0]
或使用match
:
p str.match(/^.*[C].*$/i)[0]
编辑:
或者,如果您想要找到以C
开头的第一个块,请尝试以下操作:
p str.match(/^C.*$/)[0]
答案 2 :(得分:1)
编辑添加了另外两种处理方法。最后一个是可取的。
这将做你想要的。它将搜索你的正则表达式的匹配,然后获得第一个。请注意,如果字符串没有任何匹配项,则会产生错误。
string = "[Home] (202) 121-7777
C (202) 456-1111
[mobile] 55 55 5 55555
[Work] (404) 555-1234
[Cell] (505) 555-1234
W 303-555-5555
M 777-555-5555
c 12346567s"
puts string.match(/^(.*[C].*)$/i).captures.first
puts string.match(/^(.*[C].*)$/i)
puts string[/^(.*[C].*)$/i]
答案 3 :(得分:1)
我会对此有所不同。我更喜欢将正则表达式简化为非常简单的模式:
str = <<EOT
[Home] (202) 121-7777
C (202) 456-1111
[mobile] 55 55 5 55555
[Work] (404) 555-1234
[Cell] (505) 555-1234
W 303-555-5555
M 777-555-5555
c 12346567s
EOT
使用select
或find
轻松完成正确的合作线:
str.split("\n").select{ |s| s[/c/i] }.first # => "C (202) 456-1111"
str.split("\n").find{ |s| s[/c/i] } # => "C (202) 456-1111"
我建议find
因为它只返回第一次出现。
找到所需的字符串后,使用scan
获取数字:
str.split("\n").find{ |s| s[/c/i] }.scan(/\d+/) # => ["202", "456", "1111"]
然后join
他们。当您将电话号码存储在数据库中时,您实际上不希望它们被格式化,您只需要数字。稍后再次输出格式时会发生格式化。
phone_number = str.split("\n").find{ |s| s[/c/i] }.scan(/\d+/).join # => "2024561111"
当您需要输出数字时,请根据区域电话号码表示将其分成正确的分组。你应该知道这个人的位置,因为你通常也得到他们的国家代码。基于此,您知道您应该拥有多少位数,以及组:
area_code, prefix, number = phone_number[0 .. 2], phone_number[3 .. 5], phone_number[6 .. 9] # => ["202", "456", "1111"]
然后输出它们以便正确显示:
"(%s) %s-%s" % [area_code, prefix, number] # => "(202) 456-1111"
就原始模式/^.*[C].*$/i
而言,您对正则表达式的理解存在一些问题:
^.*
说“从字符串的开头开始,找到零个或多个字符”,这并不比说/[C]
更有效。 [C]
创建一个不必要的字符集,这意味着“找到集合中的一个字母”C“;它没有任何用处,所以只需使用C
作为/C
。 .*$
人工地找到字符串的结尾,但由于你没有捕获它,所以没有任何成就,所以不要理会它。正则表达式现在是/C/
。/C/i
或/c/i
。 (或者您可以使用/[cC]/
,但为什么?)相反:
/c/i
即可。这就是所需要的。 http://rubular.com/r/uPyxACOWls /c(?:ell)?/
。 http://rubular.com/r/TkSRPWG2y6 /\bc(?:ell)?\b/
等分词标记。 http://rubular.com/r/Smo0bFs9w8 您可以获得更复杂的内容,但如果您没有使用其他模式信息完成任何操作,那么您只是在浪费正则表达式引擎的CPU时间,并且会减慢代码速度。混乱的正则表达式引擎会浪费大量的CPU时间,因此要高效并了解您要求它做的事情。