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 个元素。现在我必须拆分匹配,这显着扩大了代码。
有人可以减少我的困惑吗?
\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
被替换为什么都没有,aefg
用g
and_
和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 -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)
捕获)。