我是pythonizer的作者,perl to python converter,我正在尝试翻译一个perl split语句,它的字符串模式中包含一个反斜杠,我需要一些帮助来理解它的行为。下面是一个基于源代码的例子,我正在尝试翻译:
$s = 'a|b|c';
@a = split '\|', $s;
print scalar(@a) . "\n";
print "@a\n";
输出为:
3
a b c
现在,如果我只打印'\|'
,它会打印\|
,所以我不确定为什么在字符串模式中忽略了反斜杠。文档中并没有提到任何关于字符串被用作模式的内容,除了' '
的特殊情况。将'\|'
输入到python string split中不会拆分这个字符串。
更奇怪的是,如果我将上面的代码更改为使用双引号括起来的字符串,会发生什么情况:
@a = split "\|", $s;
则输出为:
5
a | b | c
如果我把它改成一个正则表达式,那么它的作用就像是一个单引号字符串(分成3部分),这很有意义,因为|
是正则表达式中的一个特殊字符,所以它需要被转义:
@a = split /\|/, $s;
所以我的问题是--如果一个字符串包含一个反斜杠(在单引号中,然后是双引号),那么它的拆分应该如何工作,以便我可以在python中重现它?如果它在一个拆分上,我应该从单引号输入字符串中删除所有的反斜杠,除了\\
吗?
另外,为什么"\|"
(或"|"
)上的split会将字符串拆分为5个部分?(我正在考虑在这个案例中使用punting。)
2条答案
按热度按时间iyzzxitl1#
有几个交叉问题,让我一步一步来
split
的正则表达式中的分隔符:模式中的变量除了在单引号下外都是插值的,就像在正则表达式中一样,这里的例子没有相关性。字符串\|
无论如何都是模式\|
,所以字面量|
(而不是交替)但对于双引号,则有不同之处:在
split
中,双引号下的字符串首先被插入,显然包括转义符,然后才把结果交给正则表达式引擎编译成模式。因此"\|"
变成正则表达式的模式|
,所以是的,交替!(不是正则表达式中split
之外的行为。)split
的问题上--用|
的模式,作为split "\|"
或作为split /|/
--它的工作原理就像用空字符串拆分一样,split
的特性是返回所有字符。正则表达式不这样做,对于/|/
和//
。split
的这种行为看起来没有文档记录。我可以看到类似于“split byeitherempty stringorby empty string -- well,so split by empty string"的基本原理,对于split
来说可能有一些意义。在正则表达式中,这没有多大意义:匹配“empty string -or- empty string”与第一个空字符串匹配,这仅仅是成功的结果--但是空字符串的实际模式具有非常独特的行为,我在
/|/
中没有看到这种行为。(这与split
的行为无关。)因此,拥有一个单独的/|/
--一个法律的的模式--只是令人困惑,因为它什么也不做。至于Python如何处理这个问题,OP在一个注解中提到的str.split根本没有使用正则表达式。要重现Perl的
split
操作,需要使用split from re,re.split(pattern, string,...)
。然后仔细检查细节,并使用转义的正则表达式模式测试re
中的行为。snvhrwxg2#
Perl按原样处理单引号。它插入双引号。
Split需要正则表达式,因此
'\|'
被视为正则表达式\|
,其中\
是正则表达式转义字符,意味着|
是匹配的拆分字符。Perl将"\|"
插值为|
,这是OR的正则表达式。