字符串和数字的 Perl 正则表达式 - 仅匹配最后 6 位数字

Perl regular expression for string and digits - match only last 6 digits

我需要从文件名(日期)中提取最后 6 位数字,正则表达式对我不起作用。

字符串是:name_of_file0000000546210618.A001.6476871457

我只需要包含这个:name_of_file210618.A001

我的正则表达式是:name_of_file\(\d{6}).A\d{3} - 不起作用

我也试过了:name_of_file(\d{6}).A\d{3} - 不起作用

更多详情:

我们已经使用了 name_of_file(\d{6}).A\d{3},并且已经使用了 3 年多。在这些情况下,字符串只是 name_of_file210618.A001.6476871457,正则表达式就是这样:name_of_file210618.A001。在这种情况下,这正是我所需要的,我需要处理 210618.

之前的数字

删除后跟6位的所有数字:

perl -pe 's/\d*(?=\d{6})//' <<< 'name_of_file0000000546210618.chardigits.digits'

你需要

name_of_file\K\d*(?=\d{6}\.A\d{3})

替换为空字符串。参见regex demo。详情:

  • name_of_file - 一个特定的字符串
  • \K - 匹配重置运算符从整个匹配内存缓冲区中丢弃到目前为止匹配的文本
  • \d* - 零个或多个数字
  • (?=\d{6}\.A\d{3}) - 正前瞻需要六位数,.A 和三位数立即出现在当前位置的右侧。

参见 Perl demo online:

#!/usr/bin/perl
use feature 'say';
use strict;
use warnings;
 
my $str = "name_of_file0000000546210618.A001.6476871457";
say $str =~ s/name_of_file\K\d*(?=\d{6}\.A\d{3})//r;

输出:

name_of_file210618.A001.6476871457

你的正则表达式的原因

name_of_file\(\d{6}).A\d{3}
#           ^^--- escaped parenthesis

不起作用是因为它需要在您的字符串中使用文字括号 (。由于有 none,因此永远不会匹配。

这个正则表达式

name_of_file(\d{6}).A\d{3} 

将不匹配,因为您将其“锚定”在 name_of_file.A 之间,中间不允许有字符。

允许额外填充数字的最简单解决方法是在捕获区域之前简单地添加 \d*。您还应该转义 . 因为它是一个正则表达式元字符,意思是“匹配除换行符之外的任何字符”。

name_of_file\d*(\d{6})\.A\d{3}

现在这将允许正则表达式更松散地匹配字符串,例如

name_of_file0000000546210618.A001.6476871457
#           ^^^^^^^^^^---- unneeded numbers

同样,您可以删除数字前的锚点

(\d{6})\.A\d{3}

在正则表达式中包含字符串 name_of_file 对我来说很奇怪。如果它是实际文件名的占位符,则意味着您在正则表达式中对文件名进行了硬编码,这意味着它只会匹配确切的文件名,而不会匹配其他任何内容。通常,您希望正则表达式匹配多个 不同 类型的字符串。我希望正则表达式匹配不同的文件名看起来像:

 [\pL_]+\d*(\d{6})\.A\d{3}
#^^^^^^-- matching letters and underscore

看起来您需要捕获的不是数字,就像您的正则表达式显示的那样,而是文件名,在这样的字符串中:name_of_file210618.A001。在这种情况下,您将需要执行更多操作。可以通过替换来执行以删除不需要的字符,但仅使用正则表达式和连接要简单得多,就像这样

use strict;
use warnings;
use Data::Dumper;

while (<DATA>) {
    my ($name, $num) = /([\pL_]+)\d*(\d{6}.A\d{3})/;
    my $str = join '', $name, $num;
    print Dumper $str;
}

__DATA__
name_of_file210618.A001.6476871457
name_of_file0000000546210618.A001.6476871457
foo_of_bar210618.A001.6476871457

这将打印

$VAR1 = 'name_of_file210618.A001';
$VAR1 = 'name_of_file210618.A001';
$VAR1 = 'foo_of_bar210618.A001';