解释在字符串模式中使用反斜杠进行Perl拆分

1sbrub3j  于 2022-11-15  发布在  Perl
关注(0)|答案(2)|浏览(189)

我是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。)

iyzzxitl

iyzzxitl1#

有几个交叉问题,让我一步一步来

  • Perl的split在第一个参数中采用正则表达式模式来标识分隔符,它通过该分隔符来拆分字符串。
  • 对于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中的行为。

snvhrwxg

snvhrwxg2#

Perl按原样处理单引号。它插入双引号。
Split需要正则表达式,因此'\|'被视为正则表达式\|,其中\是正则表达式转义字符,意味着|是匹配的拆分字符。Perl将"\|"插值为|,这是OR的正则表达式。

相关问题