正则表达式不应与括号内的数字匹配

时间:2013-12-14 12:42:34

标签: regex perl

我有一段经文,而且有数字。我希望每个编号的诗歌都在单独的行中,所以我在它们之前添加一个新行,但我有一些括号也有数字。它们也被新线代替。我不想匹配括号内的数字。我用了

$_=~s/(\d+)/\n$1 /gs;

使用此输入:

1Hello2Hai (in 2:3) 3hi 4 bye

但它也取代了paranthesis里面的数字。

必需的输出:

1 Hello
2 Hai (in 2:3)
3 hi
4 bye

实际输出:

1 Hello
2 Hai (in
2:
3)
3 hi
4 bye

如何构造正则表达式,使其与括号内不匹配。我对perl使用regex

2 个答案:

答案 0 :(得分:4)

你可以试试这个:

#!/usr/bin/perl 
use strict;
use warnings;

my $stro = <<'END';
1Hello2Hai (in 2:3) 3hi 4 bye
END

$stro =~s/(\((?>[^()]++|(?1))*\))(*SKIP)(*FAIL)|\s*(\d+)\s*/\n$2 /g;

print $stro;

模式细节:

想法是跳过括号中的内容。为此,我尝试首先将括号与此递归子模式匹配:(\((?>[^()]++|(?1))*\))并使子模式失败并强制正则表达式引擎不使用(*SKIP)和{{1}的其他替代方法重试子字符串}回溯控制动词。

如果子模式稍后失败,

(*FAIL)强制不重试左侧匹配的内容。

(*SKIP)强制子模式失败。

另一种方式:

正如您在the perl documentation中所读到的,回溯控制动词是一个实验性的正​​则表达式功能,应该在生产代码中提及。 (但是,此功能存在多年。)

以下是一种没有这些功能的简单方法:您匹配数字前面的所有内容,然后使用(*FAIL)功能将其从匹配结果中删除:

\K

答案 1 :(得分:1)

使用此模式
{/ 1}}带有/ g选项
并替换为(\D+)(\d+)(?=((?!\)).)*\(|[^()]*$) Demo

或调整缩进使用此模式
{/ 1}}带有/ g选项
并替换为$1\n$2 Demo
除了你必须摆脱第一个空行