Во-первых, все это можно написать гораздо приятнее, установив переменные для компонентов этого слишком длинного шаблона, а затем используя их в самом шаблоне.
Практически весь основной синтаксис регулярных выражений, которыйподдерживается на обоих этих языках одинаково или достаточно близко, так что я не буду здесь перечислять, что означает [..]
или \s
.Для перевода требуется общая операция (операторы, функции и т. Д.) И несколько используемых флагов
Группа регулярных выражений использует оператор substitution , $x =~ s/pattern/repl/
, посредством чего подстановки выполняются для переменной $x
(и на месте).В Python это re
Конечные модификаторы /gis
в Perl регулярное выражение означают: найти изаменить все вхождения шаблона (/g
), игнорировать регистр (/i
) и заставить .
сопоставить что угодно (/s
), включая символ новой строки.
В python, чтобы заменить все вхождения шаблона, просто опустите count
(или установите его в ноль), который был бы четвертым аргументом в re.sub
ниже (между string
ифлагов), в то время как для двух других есть флагов : IGNORECASE (или I) и DOTALL (или S)
В общей сложности у нас есть
import re
result = re.sub(pattern, replacement, string, flags=re.I|re.S)
, который возвращает новую строку, в отличие от замены по умолчанию в Perl, поэтому присвойте re.sub
обратно string
, если вы хотите эмулировать данное регулярное выражение.
В дополнение к ссылке perlre
и perlop
, связанным выше, некоторые другие полезные ресурсы для регулярного выражения Perl - это учебное пособие perlretut и краткий справочник perlreref ,
Вот первое регулярное выражение для более полного примера.Я хотел бы сначала переписать его на стороне Perl
# Opening "item", a phrase, and phrases with alternation
my $item = qr/(item\s+7[^0-9a-z\"]*management(?:[^0-9a-z]{0,3}s)?\s+/;
my $phrase = qr/discussions?\s+and\s+analysis\s+of\s+/;
my $pa1 = qr/(?:financial\s+conditions?\s+|results\s+of\s+operations?)/;
my $pa2 = qr/(?:\s+and\s+results\s+of\s+operations?|\s+and\s+financial\s+conditions?)?)/
$x =~ s/([^\"])$item$phrase$pa1$pa2/$1#######ITEM7:$2#######/gis;
Я использовал qr для построения правильного шаблона регулярных выражений (по духу похож на объект re.compile
в Python)в то время как в этом случае также подойдет обычная строка.
Я заменил устаревшие \1
и \2
на стороне замены на $1
и $2
.(\1
используется в качестве обратной ссылки для работы в соответствующей стороне регулярного выражения.)
В Python с гигантским шаблоном, как указано в вопросе
patt = re.compile("...", flags=re.I|re.S)
string = patt.sub(r"\g<1>#######ITEM7:\g<2>#######/", string)
или, лучше, сначала сформируйте подшаблоны, как указано выше (многоточие указывает на то, что они должны быть заполнены)
item = "(item\s+..."
phrase = "discussions?..."
pa1 = "(?:financial\s..."
pa2 = "(?:\s..."
patt = re.compile(item+phrase+pa1+pa2, flags=re.I|re.S)
string = patt.sub(r"\g<1>#######ITEM7:\g<2>#######/", string)
Использование re.compile
ни в коем случае не является обязательным;re.sub
, приведенное выше, чаще всего точно так же.Но я считаю re.compile
хорошим устройством для организации кода (оставляя без внимания вопрос эффективности).
Если вы не в Python 3 (пока), вам понадобится re.compile
для использования флагов.
Насколько я понимаю, весь Python сам по себе одинаков, поэтому вы можете просто скопировать его.
Пример: (?:[^0-9a-z]{0,3}s)?
работает следующим образом
без захвата (?: ... )
группирует вещи (но не сохраняет их), так что это можно сделать
опционально с (?: ... )?
с последним ?
(соответствует 0 или 1 раз, в целом)
класс отрицанных символов [^0-9a-z]
соответствует чему-либо, кроме цифры или строчной буквы ...
от нуля до трех раз с [^0-9a-z]{0,3}
(но не нужно 0
как {3}
означает то же самое)
s
в конце является просто буквенным символом s
Обратите внимание, что с флагом /i
(re.I
) приведенный выше класс отрицанных символов исключает все буквы.
Последний оператор с регулярным выражением
my @M = $y =~ m/(...)+/g;
соответствует всем вхождениям (/g
) данного шаблона в строке $y
(оператор совпадения m//
связан с $y
оператором =~
) и возвращает список совпадений, присвоенный массиву @M
.
В Perl оператор совпадения может вернуть 1
или пустую строку (true / false) или список с фактическими совпадениями, в зависимости от того, в каком context он находится. Здесь контекст списка навязывается ему тем фактом, что выражение $y =~ m/.../
присваивает массиву .
Я удалил ненужные скобки выше и добавил объявлениепеременной, my @M
.Я не вижу ничего интересного в этом длинном паттерне, поэтому я оставляю это в стороне.
Вы получаете это в Python при базовом использовании re.findall
Редактирование вопроса. Код
for($i = 0; $i < scalar(@X); ++$i)
перебирает индексы массива @X
, но гораздо приятнее (и лучше) это
for my $i (0..$#X)
с использованием синтаксиса $#X
для последнего индекса @X
и диапазонаоператор n .. m
.Синтаксис $X[$i]
предназначен для элемента массива @X
с индексом $i
.Массивы в Perl основаны на 0.
Тогда внутри цикла есть простое условие, основанное на совпадении с регулярным выражением
if ( $X[$i] =~ m/^(ITEM(?:7|7A|8)):(.*)$/s )
, где оператор совпадения m//
здесь возвращает 1
/''
(true / false), находясь в скалярном контексте (условие оператора if
в конечном счете требует логического значения).Поэтому, если есть совпадения, if
получает ненулевое число и оценивается как true, в противном случае код падает до else
.
Модификатор /s
, также встречающийся в регулярных выражениях подстановки, заставляет .
также соответствовать символам новой строки, чтобы весь шаблон мог совпадать между строками в многострочной строке.
В обоих if
- else
устанавливаются элементы ветвей других массивов (@Z
и @Y
), и, если было совпадение, используются шаблоны, захваченные регулярным выражением ($1
и $2
).
Наконец, .
является оператором конкатенации, и выражение $i . ':' . $1
объединяет значение $i
, литерал :
и (первый захват) $1
.length_in_words()
является подпрограммой.
Редактировать: подпрограмма length_in_words()
добавлена в вопрос.
Короче говоря: подпрограмма занимаетстрока и возвращает количество слов в ней.
Сдвиг удаляет первый элемент из массива.По умолчанию это делается для @_
(когда он находится в подпрограмме), массива с аргументами функции.Таким образом, $x
является входной строкой, с которой была вызвана функция.
Регулярное выражение сопоставляет все слова (\S+
в модификаторе /g
) в $x
и возвращает тот список, который назначенв массив @k
.Затем scalar
принимает количество элементов в массиве, что возвращается.