我需要有关此正则表达式的帮助,以仅捕获字符串中的精确匹配项并将其放入变量中
我只想推断这些值(固定列表;没有其他数字):
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;
}
我怎样才能将我想要的精确匹配捕获到变量中然后显示它?也许我就是只见树木不见森林。预先感谢您的帮助
最佳答案
使用给定的模式列表
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/
这可能更有效,因为它只启动正则表达式引擎一次,但另一方面,只有几个(或一个?)选项,我们确实参与了所有开销以形成交替。
根据详细信息,您可能希望先按长度
排序,然后按最长或最短
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
。如果确定它有前导零,您可以进一步限制它。
关于regex - perl正则表达式仅将字符串中的完全匹配捕获到变量中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36559388/