我尝试在perl元素之间用空格来分割字符串,然而,每个元素也可能包含空格(通过双引号或用括号括起来)。
例如,包含以下内容的字符串:
for element in hydrogen helium "carbon 14" $(some stuff "here") FILE
我希望最后得到一个类似(hydrogen, helium, "carbon 14", "$(some stuff "here")", FILE)
的数组
我可以处理for element in
位并将其余的作为一个字符串。
@elements = split /(?<=\"[^\"]*\")\s+(?=\"[^\"]*\")/, $list
虽然正则表达式只匹配引号之间白色(在www.example.com上查看regexr.com),但Perl程序给了我Lookbehind longer than 255 not implemented in regex
。
有没有更好的方法在空格上使用split
来考虑这个问题?我的正则表达式哪里出错了?
2条答案
按热度按时间5w9g7ksd1#
匹配带引号或圆括号的表达式,* 然后 * 与非空格序列交替
用你的琴弦和一些简单的变化来测试。
这里假设两个分隔符都没有嵌套:连续引号之间的表达式作为一个元素(即使它有括号中的子表达式),括号内的表达式也是如此(即使它有引号)。2这是从问题中推断出来的。
我允许括号前后的字符序列不包含空格,以适应前面的
$
,如果它确实 * 只能 * 是前面的一美元,请调整它。s3fp2yjn2#
在这种情况下,我倾向于使用解析方法,这样你就不必使用一个正则表达式来做几件不同的事情,这一点很重要,因为字符串的复杂性会发生变化,尽管这看起来需要更多的代码,它是基本的Perl,您可以将它放在子例程中,我可以轻松地添加另一个令牌类型,而不会干扰代码的机制或重写模式。我在如何从一个模式中获取未知数量的捕获中也使用了这个技巧:
您可以对branch reset operator执行许多相同的操作,每次捕获交替为
$1
:这比zdim's answer要复杂一些,但是它更灵活,比如说,你决定不需要在
"carbon 14"
两边加上引号,这是一个非常容易的修正,因为正则表达式的结构没有改变,你只需要改变处理这个标记的子模式:你可能不需要这种额外的灵活性。我通常会发现在这类任务中我会遇到额外的奇怪情况,所以我从灵活的解决方案开始。在你做了几次之后,这并不是一件大事。
至于你的错误,你得到了:
正则表达式中未实现长度超过255的Lookbehind。
在v5.30之前,你不能有一个variable-width lookbehind。现在它是一个实验特性,但是模式必须事先知道它不会超过255个字符。你的模式有
(?<=\"[^\"]*\")
,并且*
是零或更大。这个更大的值可以大于255,所以它是一个非法的模式。regexr.com 使用PCRE,PCRE过去代表“Perl Compatible”,但是它们之间的差异已经很大,有些东西看起来在其他语言中可以正常工作,但在Perl中就不行了。这通常不是问题,但lookbehinds是区别之一。