perl正则表达式之间的差异在Moses中的两个数字之间添加点

2024-03-29 15:56:27 发布

您现在位置:Python中文网/ 问答频道 /正文

上下文中,我正在尝试将一个Perl代码从https://github.com/moses-smt/mosesdecoder/blob/master/scripts/tokenizer/normalize-punctuation.perl#L87移植到Python中,Perl中有一个正则表达式:

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

如果我在给定输入文本123 45的Perl脚本中尝试,它将返回带点的相同字符串。作为一个健全的检查,我也尝试了命令行:

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

[输出]:

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

甚至当我们试图在Moses code中的正则表达式前后打印字符串时,也就是说

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 $_;
    }

[输出]:

123 45
123 45
123 45

我们看到在正则表达式前后,字符串没有变化。你知道吗

我的部分问题是:

  • Python的\g<1>.\g<2>正则表达式是否等同于Perl的$1.$2?你知道吗
  • 为什么Perl正则表达式没有在Moses中的两个数字组之间添加句号.?你知道吗
  • 如何在Python regex中复制Moses中的Perl行为?你知道吗
  • 如何在Moses的Perl正则表达式中复制Python的行为?你知道吗

Tags: httpsmastercomrawlanguageperleqnormalize
1条回答
网友
1楼 · 发布于 2024-03-29 15:56:27

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 a020?你知道吗

附言。 关于在regex中添加加号的评论:这里不需要加号,因为在两个相邻的数字之间添加点符号就足够了,不需要查找完整的数字

相关问题 更多 >