2

我的字符串是$tables="newdb1.table1:100,db2.table2:90,db1.table1:90". 我的搜索字符串是 db1.table1,我的目标是提取之后的值:(即90在本例中)。

我在用:

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

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

你能给我一个正则表达式来匹配一个以换行符开头或前面有逗号的字符串。

4

3 回答 3

6

使用单词边界

if ($tables =~ /\bdb1.table1:(\d+)/) { print $1; }
         here __^^
于 2013-05-16T12:07:57.867 回答
2

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

于 2013-05-16T12:08:44.760 回答
0

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

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

但这可能会因错误而失败

正则表达式 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的作者Randal Schwartz 提出的经验法则。当您知道要保留什么以及要丢弃什么时,请使用捕获。在您的情况下,您有一个混合:您想丢弃逗号分隔符,并且您想保留某个表的冒号后面的数字。写成split

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

输出:

[90]
于 2013-05-16T13:38:11.403 回答