У меня есть текстовые файлы, содержащие строки, такие как:
2/17/2018 400000098627 =2,000.0 $2.0994 $4,387.75
3/7/2018 1)0000006043 2,000.0 $2.0731 $4,332.78
3/26/2018 4 )0000034242 2,000.0 $2.1729 $4,541.36
4/17/2018 2)0000008516 2,000.0 $2.219 $4,637.71
Я сопоставляю их с /^\s*(\S+)\s+(?:[0-9|\)| ]+)+\s+([0-9|.|,]+)\s+\$/
Но у меня также есть некоторые файлы со строками в совершенно другом формате, которые я сопоставляю с другим регулярным выражением.Когда я открываю файл, я определяю, какой формат и назначаю $pat = '<regex-string>';
в блоке switch / case:
$pat = '/^\s*(\S+)\s+(?:[0-9|\)| ]+)+\s+([0-9|.|,]+)\s+\$/'
Но символ ?
, который представляет группу без захвата, которую я использую для сопоставления, повторяется после повторовдата и до первой суммы валюты приводит к тому, что интерпретатор Perl не может скомпилировать сценарий, сообщая об отмене:
syntax error at ./report-dates-amounts line 28, near "}continue "
Если я удаляю символ ?
или замену ?
на \?
, экранированныйили сначала назначьте $q = '?'
, а затем замените ?
на $q
внутри "
строкового назначения (т. е. $pat = "/^\s*(\S+)\s+($q:[0-9|\)| ]+)+\s+([0-9|.|,]+)\s+\$/";
), который скрипт скомпилирует и запустит.Если я назначу строку регулярного выражения за пределами блока switch/case
, это также работает нормально.Perl v5.26.1.
Мой код также не содержит }continue
, что, как сообщается в сбое компиляции, вероятно, является своего рода преобразованием кода switch/case
с помощью Switch.pm
в нечтородной компилятор захлебывается.Это какая-то ошибка в Switch.pm?Он не работает, даже когда я использую given/when
точно таким же образом.
#!/usr/local/bin/perl
use Switch;
# Edited for demo
switch($format)
{
# Format A eg:
# 2/17/2018 400000098627 =2,000.0 $2.0994 $4,387.75
# 3/7/2018 1)0000006043 2,000.0 $2.0731 $4,332.78
# 3/26/2018 4 )0000034242 2,000.0 $2.1729 $4,541.36
# 4/17/2018 2)0000008516 2,000.0 $2.219 $4,637.71
#
case /^(?:april|snow)$/i
{ # This is where the ? character breaks compilation:
$pat = '^\s*(\S+)\s+(?:[0-9|\)| ]+)+\s+\D?(\S+)\s+\$';
# WORKS:
# $pat = '^\s*(\S+)\s+(' .$q. ':[0-9|\)| ]+)+\s+\D' .$q. '(\S+)\s+\$';
}
# Format B
case /^(?:umberto|petro)$/i
{
$pat = '^(\S+)\s+.*Think 1\s+(\S+)\s+';
}
}