Regex 使用sed在字符串中插入下划线

Regex 使用sed在字符串中插入下划线,regex,sed,Regex,Sed,我试图使用sed在非空白字符字符串的每个大写字母之前插入。,除非它在开头。(我想转换camelcase格式的字符串,这些字符串偶尔包含几个相邻的大写字母,甚至标点符号。) 期望的行为: 输入: aaaaaaaaaaaaaa 输出: Aa_Aa_Aa_A_A_A_A_A_A_A 我尝试使用以下命令: sed -e "s/\(\S\)\([[:upper:]]\)/\1_\2/g" 但它在上述输入的最后两个字符串上失败,产生以下结果: Aa_Aa_Aa A_Aa A_Aa 我真的不明白为什么

我试图使用sed在非空白字符字符串的每个大写字母之前插入
,除非它在开头。(我想转换camelcase格式的字符串,这些字符串偶尔包含几个相邻的大写字母,甚至标点符号。)

期望的行为:

输入:

aaaaaaaaaaaaaa
输出:

Aa_Aa_Aa_A_A_A_A_A_A_A
我尝试使用以下命令:

sed -e "s/\(\S\)\([[:upper:]]\)/\1_\2/g"
但它在上述输入的最后两个字符串上失败,产生以下结果:

Aa_Aa_Aa A_Aa A_Aa
我真的不明白为什么


我使用的是GNU sed 4.2.2。

问题在于,对于单个
s///g
,正则表达式匹配不能重叠(并且对于进一步的匹配不考虑先前替换的结果)

对于
AAA
,第一个匹配是

AAA
^^
| \
\1 \2
更换后,我们有
A_AA
,最右边的两个A之间有“当前位置”:

A_uaa
^
下一场比赛从这里开始
然后我们再次尝试匹配,但是我们已经没有字符了
\S
匹配最后一个
A
,但仅此而已:之后没有大写字符

为了实现这一点,我们必须以某种方式将中间的
A
匹配为第一次替换的
\2
和第二次替换的
\1
,我不知道如何使用sed实现这一点


(使用perl会很容易,因为这样您就可以使用look behind/look ahead,它在匹配中不包括周围的文本:
perl-pe的/(?问题是,对于单个
s///g
,正则表达式匹配不能重叠(并且对于进一步的匹配,不考虑先前替换的结果)

对于
AAA
,第一个匹配是

AAA
^^
| \
\1 \2
更换后,我们有
A_AA
,最右边的两个A之间有“当前位置”:

A_uaa
^
下一场比赛从这里开始
然后我们再次尝试匹配,但字符已用完。
\S
匹配最后一个
A
,但仅此而已:之后没有大写字符

为了实现这一点,我们必须以某种方式将中间的
A
匹配为第一次替换的
\2
和第二次替换的
\1
,我不知道如何使用sed实现这一点


(使用perl会很容易,因为这样您就可以使用look-behind/look-ahead,它在匹配中不包括周围的文本:
perl-pe/(?我假设您的示例输入错误,因为
aaaa
提供给您提供的替换没有任何作用。它也不是驼峰大小写标识符。它应该是
AaAaAa
,对吗

如果是这样的话,那么您可以让
sed
通过使其循环直到不再发生替换来执行您需要的操作:

echo "AaAaAa AAA AAA" | sed -e ':x;s/\([^[:space:]_]\)\([[:upper:]]\)/\1_\2/g;tx' 
产生

Aa_Aa_Aa A_A_A A_A_A 

我假设您的示例输入错误,因为
aaaa
提供给您提供的替换没有任何作用。而且它也不是驼峰大小写标识符。它应该是
AaAaAa
,对吗

如果是这样的话,那么您可以让
sed
通过使其循环直到不再发生替换来执行您需要的操作:

echo "AaAaAa AAA AAA" | sed -e ':x;s/\([^[:space:]_]\)\([[:upper:]]\)/\1_\2/g;tx' 
产生

Aa_Aa_Aa A_A_A A_A_A 
这可能适用于您(GNU-sed):

将所有
\uu
转换为唯一的备选方案。在大写字符前插入
\u
。删除任何前导
\u
。重新转换原始
\u

如果您首先没有任何前导的
\uu
,那么这就足够了:

sed -r 's/[[:upper:]]/_&/g;s/\b_//g' file
这可能适用于您(GNU-sed):

将所有
\uu
转换为唯一的备选方案。在大写字符前插入
\u
。删除任何前导
\u
。重新转换原始
\u

如果您首先没有任何前导的
\uu
,那么这就足够了:

sed -r 's/[[:upper:]]/_&/g;s/\b_//g' file

我也这么怀疑。然后我会尝试使用perl。你不需要去perl,但你确实需要澄清你的需求,因为现在还不清楚你想做什么。请看你问题下@BenjaminW的评论。我也这么怀疑。我会尝试使用perl。你不需要去perl,但你确实需要澄清你的需求现在还不清楚你想做什么。请看你问题下@BenjaminW的评论。