Perl 正则表达式匹配分隔字符串

Posted

技术标签:

【中文标题】Perl 正则表达式匹配分隔字符串【英文标题】:Perl Regex match delimited string 【发布时间】:2018-02-16 14:35:46 【问题描述】:

在我的一生中,我无法用 Perl 语法来解决这个问题。我已经设法让这种风格在 javascript 中工作,其中 N 是匹配号。

^(?:[^\|]*\|)N([^\|]*)

我也尝试过匹配任何不是管道的东西,但是我似乎无法编写正则表达式来提取我需要的 Perl 风格的匹配索引。有什么指点吗?

数据看起来像这样

字符串|另一个字符串|测试|也许更多的文本

当第一个正则表达式在正则表达式调试器中运行时,它会产生这个(这是我想要运行的)。

^(?:[^\|]*\|)0([^\|]*) produces 'astring' ^(?:[^\|]*\|)3([^\|]*) produces 'maybe some more text'

但是,当我在 Netezza(Perl Regex,这是我需要它运行的地方)中运行它时,它会产生:

^(?:[^\|]*\|)0([^\|]*) produces 'astring' ^(?:[^\|]*\|)3([^\|]*) produces 'astring| another string|test|maybe some more text'

更新: 问题解决了 正则表达式没问题,但是我是个笨蛋,没有正确使用 Netezza 中的函数。这导致了正则表达式的过度复杂化。下面的例子 REGEXP_EXTRACT(column, '[^\|]+',1 ,4 )

【问题讨论】:

你到底想做什么? 如果我尝试你的正则表达式,我在捕获组中得到了你想要的,那有什么问题呢? regex101.com/r/w2V2sK/1 抱歉,如果不清楚。我已经更新了我的问题 还是不明白问题出在哪里,你要的部分还是存放的是第一个捕获组。你应该能够得到你想要的,存储到变量 $1 中。如果你不明白我在说什么,请点击我之前评论中的链接;) 也许这就是我运行查询的方式 【参考方案1】:

我认为你可以重复 [^\|] 1 次或更多次 [^\|]+

^(?:[^\|]+\|)N([^\|]+)

^(?:[^\|]+\|)0([^\|]+) 将捕获组 1 中的 astring

^(?:[^\|]+\|)3([^\|]+) 将捕获组 1 中的 maybe some more text

【讨论】:

当我运行 ^(?:[^\|]+\|)0([^\|]+) 它确实返回字符串。但是,当我将 N 更改为 3 时,它会返回整个字符串 'astring|另一个字符串|测试|也许更多的文本'。有没有可能只是 Perl 引擎? 你检查第一个捕获组了吗? 你能解释一下你的意思吗? 正则表达式([^\|]+) 的最后一部分使用括号来捕获您在组中的值。例如,您可以检查 this page 关于分组和捕获的信息。如果使用 0,则完整匹配是“astring”,与第 1 组相同,如果使用 3,则完整匹配是整个句子,第 1 组中的值是“也许还有一些文本” ”。如果单击示例链接,您可以看到蓝色突出显示的是完全匹配,绿色突出显示的是第一个捕获的组。 问题解决了 Regex 没问题,但是我是个笨蛋,没有正确使用 Netezza 中的函数。这导致了正则表达式的过度复杂化。下面的例子 REGEXP_EXTRACT(column, '[^\|]+',1 ,4 )【参考方案2】:

当你的数据被分隔时,你想要的工具不是一个神奇的正则表达式,而是一个拆分:

#!/usr/bin/env perl

use strict;
use warnings;

my $target_field = 3;
my $str = "astring| another string|test|maybe some more text";

print +(split (/\|/, $str))[$target_field]

【讨论】:

不幸的是,Netezza 下面是 Perl 风格的正则表达式,而不是 Perl 本身。 那么实际上不是 perl 问题?

以上是关于Perl 正则表达式匹配分隔字符串的主要内容,如果未能解决你的问题,请参考以下文章

Perl 正则匹配经验记录

将多个正则表达式匹配之一分配给变量作为 Perl 单行(取消引用数组?)

Perl:匹配文件中的正则表达式

Perl正则表达式匹配多行文件与匹配变量如何处理换行

Perl正则表达式例子

Perl:转义字符串中的特殊字符以匹配正则表达式