【问题标题】:perl regex to capture into variable only an exact match within a stringperl 正则表达式仅将字符串中的完全匹配捕获到变量中
【发布时间】:2016-08-02 05:54:47
【问题描述】:

我需要这个正则表达式的帮助来仅捕获字符串中的完全匹配并将其放入变量中

我只想推断这些值(固定列表;没有其他数字):

004010H222A1 or 
004010H223A2 or 
004010H220A1 or 
004010H279A1 or 
004010H279A1 or 
004010H217 

从给定的字符串

示例:

$str = "this is the code 004010H222A1 the rest is irrelevant";
$str = "the random number is 004010H223A2 ** anything else is irrelevant";
$str = "the last lottery number 004010H220A1 ~~ the rest is irrelevant";
$str = "yet another random sentence 004010H279A1 the rest is irrelevant";
$str = "any sentence before what i want 004010H279A1 the rest is irrelevant";
$str = "last winning number 004010H217~~~";


if ($str =~ /\b(004010H[2][1|2|7][0|2|3|7|9])(A[1|2])?\b/){
print "found exact match\n";
##put result into a variable
##example:
## $exact_match = <found eg 004010H222A1>; 
##print $exact_match;
}

我怎样才能将我想要的内容精确匹配到一个变量中然后显示它?也许我就是只见树木不见森林。提前感谢您的帮助

【问题讨论】:

  • ^.*(004010H[0-9A]{0,10})
  • 或者这个只是那个集合:^.*(004010H222A1|004010H223A2|004010H220A1|004010H279A1|004010H279A1|004010H217)

标签: regex perl


【解决方案1】:

使用给定的模式列表

my @fixed = qw(004010H222A1 004010H223A2 004010H220A1 
    004010H279A1 004010H279A1 004010H217);

my $str = "this is the code 004010H222A1 the rest is irrelevant";

my @found = grep { $str =~ /$_/ } @fixed;

匹配字符串中所有此类模式的内容。请注意,您可能需要单词边界 (/\b$_\b/),尽管如果周围文本中的模式如此不同,如图所示。如果模式本身包含任何非单词字符,那么您需要为“边界”构建子模式。

如果您确定字符串中只有一个或只需要第一个

my ($found) = grep { $str =~ /$_/ } @fixed;

或者先用交替构造模式

my $re = join '|', map { quotemeta } @fixed;

my $found = $str =~ /$re/;  # consider using word-boudaries /\b$re\b/

这可能更有效,因为它只启动一次正则表达式引擎,但另一方面,只有几个(或一个?)选项,我们确实参与了所有开销来形成交替。

根据详细信息,您可能希望按lengthfirst 排序,最长或最短

my $re = join '|', map { quotemeta } sort { length $a <=> lenght $b } @fixed;
...

请参阅this post,了解这些选项背后的原因。


如果您有更多的可能性,使用问题中显示的确切模式,模式是:数字后跟字母或数字,以非字母数字结尾。

my $pattern = qr/([0-9]+[a-zA-Z0-9]+)[^a-zA-Z0-9]/;

my ($found) = $str =~ /$pattern/;

如果模式前面紧跟非数字字符(如~),则上述匹配,而不仅仅是空格。它还允许使用小写字母,如果它们不存在则删除a-z。如果确定它有前导零,您可以进一步限制它。

【讨论】:

  • 就是这样!非常感谢。一直在玩,我喜欢你的主意。再次感谢
  • @user2585000 欢迎您,很高兴您喜欢它 :) 当您拥有固定模式列表时,这是一个不错的小“技巧”​​。
【解决方案2】:

只是把我的两分钱放进去:

\b004010H2[127][02379](?:A[12])?\b
# \b - match a word boundary
# match 004010H2 literally
# [127] one of 1,2 or 7
# followed by one of 0,2,3,7 or 9
# (?:....)? is a non capturing group and optional in this case

提示: 显然,这可以匹配您的数字,但也可以匹配其他组合,例如 004010H210A2。这完全取决于您的输入字符串。如果您只有这六个选项,那么使用简单的字符串函数可能会更安全。
请参阅 a demo on regex101.com

【讨论】:

  • thnx,该演示网站帮助调试了一些提出的想法。 thnx 还用于指出可选部分捕获组
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-05-03
  • 2020-12-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-08-06
  • 1970-01-01
相关资源
最近更新 更多