sed regexp 文本处理捕获分组引用交替混淆

mr.*_*tee 5 sed perl text-processing regular-expression

sed 的捕获分组 ALTERNATION 未按预期工作。

虽然交替的优先级最低,但这里是混淆:

echo "abcd_aefghi" | sed -r "s/(a)(b)(c)(d)|(a)(e)(f)(g)/\8/g;"

observed result --> _ghi
expected result --> error: invalid reference \8 RHS

a--bcd | # Logical alternation (Not bitwise!!)
#must be different separated logical state processing!! 
#not involvement of look behind registered reference grouping Counting!!
a--efg ;
Run Code Online (Sandbox Code Playgroud)

sed -r "s/(a)((b)(c)(d)|(e)(f)(g))/\8/;"
observed result --> _ghi
Run Code Online (Sandbox Code Playgroud)

更多的困惑,如果

sed -r "s/(a)(b)(c)(d)()|((a)(e)(f)(g))/\8/g"

observed result --> _ehi
Run Code Online (Sandbox Code Playgroud)

也更加混乱

sed -r "s/(a)(b)(c)(d)()||||i am Not comment, Whats going here?|||||||((a)(e)(f)(g))/\8/g"

observed result --> _ehi
expected result --> full parsing error, because "||"
Run Code Online (Sandbox Code Playgroud)

最糟糕的是内部分组匹配

echo "aBcB_aCfC" | sed -r "s/(a)((B)(c)(\1)|(C)(f)(\1))/\4/g;"
#Infield twin uppercase's must match!
observed result --> aBcB_aCfC
expected result --> c_f
Run Code Online (Sandbox Code Playgroud)

perl -pe 重复同样的问题!

问题是引用计数超出了交替范围,而不是在识别出交替符号后重置计数。

Fedora 20 上的 sed 版本 4.2.2。

当然,我在这里给出了非常通用的基本问题。

真正的脚本是非常复杂的长文本原始解析。

我最初的目标是打印每个交替质量分组中的第 4 个元素。现在我必须拆分匹配,这显着扩大了代码。

有人可以减少我的困惑吗?

Sté*_*las 7

\x扩展到第 x捕获组中捕获的内容,捕获组根据正则表达式中左大括号的出现从左到右编号。

echo "abcd_aefghi" | sed -r "s/(a)(b)(c)(d)|(a)(e)(f)(g)/\8/g;"
                               1  2  3  4   5  6  7  8
Run Code Online (Sandbox Code Playgroud)

该正则表达式匹配两次。一次abcd(第 8捕获组捕获任何内容)和一次aefg,第 8捕获组捕获g. Soabcd被替换为什么都没有,aefggand_hi并且保持不变,所以你得到_ghi了预期的结果。

在:

sed -r "s/(a)(b)(c)(d)()|((a)(e)(f)(g))/\8/g"
          1  2  3  4  5  67  8  9  10
Run Code Online (Sandbox Code Playgroud)

你得到,_ehi因为第 8组现在是第 1(e)

sed -r "s/(a)(b)(c)(d)()||||i am Not comment, Whats going here?|||||||((a)(e)(f)(g))/\8/g"
          1  2  3  4  5                                               67  8  9  10
Run Code Online (Sandbox Code Playgroud)

没有什么不同。除了(尽管这不可见)因为||,会有之间空场比赛h,并i在年底额外的一个(多几个有perl)。

基于交替运算符重置数字不会产生非常有用的 API。如果您想扩展到与示例中交替两侧的4捕获组匹配的内容,您可以随时执行以下操作:

sed -r 's/(a)(b)(c)(d)|(a)(e)(f)(g)/\4\8/g'
          1  2  3  4   5  6  7  8
Run Code Online (Sandbox Code Playgroud)

这会给你与perl's相同

perl -lpe 's/(?|(a)(b)(c)(d)|(a)(e)(f)(g))/\4/g'
                1  2  3  4   1  2  3  4
Run Code Online (Sandbox Code Playgroud)

(哪里\4可以扩展到什么(d)(g)捕获)。