#regex #perl
Вопрос:
Мне нужно извлечь последние 6 цифр из имени файла (это дата), и регулярное выражение для меня не работает.
Строка является: name_of_file0000000546210618.A001.6476871457
Мне нужно знать только это: name_of_file210618.A001
Мое регулярное выражение: name_of_file(d{6}).Ad{3}
— не работает
Я тоже попробовал: name_of_file(d{6}).Ad{3}
— не работает
Более подробная информация:
Мы уже использовали name_of_file(d{6}).Ad{3}
его, и он работает уже более 3 лет. Строка в этих случаях справедлива name_of_file210618.A001.6476871457
, и регулярное выражение принимает только это: name_of_file210618.A001
. И это именно то, что мне нужно в данном случае, мне нужно обработать цифры раньше 210618
.
Комментарии:
1. Какой код вы используете?
2.
d{6}
соответствует только 6 цифрам,(
будет соответствовать буквальной открытой скобке..Ad{3}
соответствует 1 любому символу, буквенному «А», за которым следуют 3 цифры. Ничто из этого не соответствует вашей строке. Как ты думал, что это сработает?3. Кроме того, у вас действительно есть точная строка
name_of_file
в вашем регулярном выражении? Предположительно, это регулярное выражение предназначено для сопоставления множества различных строк. Эта часть вашего набора строк исправлена? Как выглядят другие струны?4. @TLP, потому что мы уже используем его, и он работает более 3 лет: name_of_file(d{6}). Ad{3} и строка в этих случаях просто name_of_file210618.A001.6476871457 — и регулярное выражение принимает только это: name_of_file210618.A001 — и это именно то, что мне нужно в моем случае, мне нужно обработать цифры до 210618…
5. Из вопроса совсем не очевидно, что на
chardigits
самом деле означает «символA
, за которым следуют три цифры». Пожалуйста, приведите реальные примеры.
Ответ №1:
Тебе нужно
name_of_fileKd*(?=d{6}.Ad{3})
Замените пустой строкой. Смотрите демонстрацию регулярных выражений. Подробные сведения:
name_of_file
— определенная строкаK
— оператор сброса соответствия отбрасывает текст, сопоставленный до сих пор, из общего буфера памяти соответствияd*
— ноль или более цифр(?=d{6}.Ad{3})
— положительный внешний вид, для которого требуется шесть цифр,.A
и три цифры должны появиться сразу справа от текущего местоположения.
Смотрите демо-версию Perl онлайн:
#!/usr/bin/perl
use feature 'say';
use strict;
use warnings;
my $str = "name_of_file0000000546210618.A001.6476871457";
say $str =~ s/name_of_fileKd*(?=d{6}.Ad{3})//r;
Выход:
name_of_file210618.A001.6476871457
Ответ №2:
Удалите все цифры, за которыми следуют 6 цифр:
perl -pe 's/d*(?=d{6})//' <<< 'name_of_file0000000546210618.chardigits.digits'
Комментарии:
1. Поскольку операция изменила внешний вид строки, это больше не будет работать.
Ответ №3:
Причина, по которой ваше регулярное выражение
name_of_file(d{6}).Ad{3}
# ^^--- escaped parenthesis
Не работает, потому что он ожидает буквальную скобку (
в вашей строке. Поскольку их нет, это никогда не будет совпадать.
Это регулярное выражение
name_of_file(d{6}).Ad{3}
Не будет совпадать, так как вы «привязали» name_of_file
его между и .A
, без учета промежуточных символов.
Самое простое исправление, позволяющее добавить дополнительные номера наполнителя, — это просто добавить d*
их перед областью захвата. Вы также должны бежать .
, так как это метасимвол регулярного выражения, который означает «соответствует любому символу, кроме новой строки».
name_of_filed*(d{6}).Ad{3}
Теперь это позволит регулярному выражению более свободно сопоставляться со строками, такими как
name_of_file0000000546210618.A001.6476871457
# ^^^^^^^^^^---- unneeded numbers
Аналогично, вы могли бы просто удалить привязку перед цифрами
(d{6}).Ad{3}
Мне странно, что строка name_of_file
находится в регулярном выражении. Если это заполнитель для фактического имени файла, это будет означать, что вы жестко кодируете имя файла в своем регулярном выражении, то есть оно будет соответствовать только этому точному имени файла и ничего больше. Обычно требуется, чтобы регексы соответствовали нескольким строкам разного типа. Я бы ожидал, что регулярное выражение, соответствующее разным именам файлов, будет выглядеть примерно так:
[pL_] d*(d{6}).Ad{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}.Ad{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';