Разница между регулярным выражением Perl для добавления точек между двумя числами в Моисее - PullRequest
0 голосов
/ 19 марта 2019

Контекст, я пытаюсь перенести код Perl в Python с https://github.com/moses-smt/mosesdecoder/blob/master/scripts/tokenizer/normalize-punctuation.perl#L87, и здесь в Perl есть это регулярное выражение:

s/(\d) (\d)/$1.$2/g;

Если я попробую его с данным сценарием Perlвходной текст 123 45, он возвращает ту же строку с точкой.В качестве проверки работоспособности я тоже попробовал в командной строке:

echo "123 45" | perl -pe 's/(\d) (\d)/$1.$2/g;' 

[out]:

123.45

И это тоже самое происходит, когда я конвертирую регулярное выражение в Python,

>>> import re
>>> r, s = r'(\d) (\d)', '\g<1>.\g<2>'
>>> print(re.sub(r, s, '123 45'))
123.45

Но когда я использую скрипт Моисея:

$ wget https://raw.githubusercontent.com/moses-smt/mosesdecoder/master/scripts/tokenizer/normalize-punctuation.perl
--2019-03-19 12:33:09--  https://raw.githubusercontent.com/moses-smt/mosesdecoder/master/scripts/tokenizer/normalize-punctuation.perl
Resolving raw.githubusercontent.com... 151.101.0.133, 151.101.64.133, 151.101.128.133, ...
Connecting to raw.githubusercontent.com|151.101.0.133|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 905 [text/plain]
Saving to: 'normalize-punctuation.perl'

normalize-punctuation.perl    100%[================================================>]     905  --.-KB/s    in 0s      

2019-03-19 12:33:09 (8.72 MB/s) - 'normalize-punctuation.perl' saved [1912]

$ echo "123 45" > foobar

$ perl normalize-punctuation.perl < foobar
123 45

Даже когда мы пытаемся напечатать строку до и после регулярного выражения в коде Моисея ,то есть

if ($language eq "de" || $language eq "es" || $language eq "cz" || $language eq "cs" || $language eq "fr") {
    s/(\d) (\d)/$1,$2/g;
    }
else {
    print $_;
    s/(\d) (\d)/$1.$2/g;
    print $_;
    }

[out]:

123 45
123 45
123 45

Мы видим, что до и после регулярного выражения в строке нет никаких изменений.

Мой вопрос по частям::

  • Является ли регулярное выражение Python \g<1>.\g<2> эквивалентным Perl $1.$2?
  • Почему регулярное выражение Perl не добавило полный стоп . междудвухзначные группы в Моисее?
  • Как реплицировать поведение Perl в Moses в регулярных выражениях Python?
  • Как реплицировать поведение Python в регулярных выражениях Perl в Moses?

1 Ответ

3 голосов
/ 19 марта 2019

Причина, по которой этот код от Moose не работает, заключается в том, что он ищет неразрывный пробел, а не только пробел. Это не легко увидеть, но hexdump может помочь вам с этим:

fe-laptop-p:moose fe$ head -n87 normalize-punctuation.perl | tail -n1 | hexdump -C
00000000  09 73 2f 28 5c 64 29 c2  a0 28 5c 64 29 2f 24 31  |.s/(\d)..(\d)/$1|
00000010  2e 24 32 2f 67 3b 0a                              |.$2/g;.|
00000017
fe-laptop-p:moose fe$ head -n87 normalize-punctuation.perl.with_space | tail -n1 | hexdump -C
00000000  09 73 2f 28 5c 64 29 20  28 5c 64 29 2f 24 31 2e  |.s/(\d) (\d)/$1.|
00000010  24 32 2f 67 3b 0a                                 |$2/g;.|
00000016

Смотрите разницу: c2 a0 против 20?

p.s. что касается комментариев о добавлении знака плюс в регулярное выражение: здесь это не нужно, так как достаточно поставить знак точки между двумя соседними цифрами и не нужно искать полные числа

...