如何匹配以新行开头或以逗号开头的字符串?

时间:2013-05-16 12:05:41

标签: regex perl

我的字符串是$tables="newdb1.table1:100,db2.table2:90,db1.table1:90"。我的搜索字符串是db1.table1,我的目标是在:之后提取值(在这种情况下为90)。

我正在使用:

if ($tables =~ /db1.table1:(\d+)/) { print $1; }

但问题是匹配newdb1.table1:100和打印100

请你给我一个正则表达式来匹配一个字符串,该字符串以换行符开头或者在它之前有逗号。

3 个答案:

答案 0 :(得分:6)

使用word boundaries

if ($tables =~ /\bdb1.table1:(\d+)/) { print $1; }
         here __^^

答案 1 :(得分:2)

if ($tables =~ /(^|,)db1.table1:(\d+)/) { print $2; }

答案 2 :(得分:0)

要回答您的确切问题,即在字符串或逗号开头之后匹配,您需要一个积极的后置断言。你可能想写一个

的模式
/(?<=^|,)db1\.table1:(\d+)/

但可能因

错误而失败
Variable length lookbehind not implemented in regex m/(?<=^|,)db1\.table1:(\d+)/ ...

因此,通过使替代方案的长度相当于一般情况下相同但在这里可行,可以保持正则表达式引擎的手。

/(?<=^d|,)db1\.table1:(\d+)/

虽然我们将其锁定,但我们一定要将结束前一个断言括起来。

while ($tables =~ /(?<=^d|,)db1\.table1:(\d+)(?=,|$)/g) {
  print "[$1]\n";
}

输出:

[90]

您还可以将\b用于具有相同输出的正则表达式字边界。

while ($tables =~ /\bdb1\.table1:(\d+)(?=,|$)/g) {
  print "[$1]\n";
}

对于最自然的解决方案,请按照 Learning Perl 的作者rule of thumb proposed by Randal Schwartz进行操作。当您知道要保留的内容时使用捕获,并在知道要丢弃的内容时使用split。在您的情况下,您有一个混合:您想要丢弃逗号分隔符,并且您希望保留某个表的冒号后面的数字。把它写成

for (split /\s*,\s*/, $tables) {    # / to fix Stack Overflow highlighting
  if (my($value) = /^db1\.table1:(\d+)$/) {
    print "[$value]\n";
  }
}

输出:

[90]