2

我是正则表达式的初学者,我正在尝试实现一些相对简单的事情:

我有一个这样排列的数据集:

1,AAA,aaaa,BBB,bbbbbb ...
2,AAA,aaaaaaa,BBB,bbb ...
3,AAA,aaaaa,BBB,bb ...

我正在考虑为 AAA 或 BBB 之后的各种长度(字母数字字符)的字符串添加大括号(这些是恒定的):

1,AAA,{aaaa},BBB,{bbbbbb} ...
2,AAA,{aaaaaaa},BBB,{bbb} ...
3,AAA,{aaaaa},BBB,{bb} ...

所以我用这种方式尝试了 sed:

sed 's/(AAA|BBB)[[:punct:]].[[:alnum:]]/\1{&}/g' dataset.txt

但是我得到了这个结果:

1,AAA,{AAA,aa}aa,BBB,{BBB,bb}bbbb, ... 
2,AAA,{AAA,aa}aaaaa,BBB,[BBB,bb}b, ...
3,AAA,{AAA,aa}aaa,BBB,{BBB,bb} ...

显然,&替换部分中的sed将是匹配的模式,但是,我&只想成为匹配模式之后的内容,我做错了什么?

我也尝试过添加单词边界,[^ ]但无济于事。我太努力了sed吗?我应该使用允许向后看的语言吗?

谢谢你的帮助!

4

3 回答 3

1

尝试这个:

sed 's/\(AAA\|BBB\),\([^,]*\)/\1,{\2}/g' dataset.txt
于 2013-10-04T08:09:48.983 回答
1

以下 sed 应该可以工作。

在 Linux 上:

sed -i.bak -r 's/((AAA|BBB)[[:punct:]])([[:alnum:]]+)/\1{\3}/g'

或者在 OSX 上:

sed -i.bak -E 's/((AAA|BBB)[[:punct:]])([[:alnum:]]+)/\1{\3}/g'

-i用于内联选项以保存输入文件本身的更改。

于 2013-10-04T07:49:51.750 回答
1

您的正则表达式中始终可以有超过 1 个捕获组,以捕获不同的部分。您甚至可以[:punct:]在第一个捕获组内移动该部分:

sed 's/((?:AAA|BBB)[[:punct:]])([[:alnum:]]+)/\1{\3}/g' dataset.txt

我不明白这.中间[:punct:][:alnum:]在做什么。所以,我删除了它。因此,您可能已经注意到,正则表达式匹配以下模式:

{AAA,aa}
{BBB,bb}

即,它在AAAand之后仅匹配 2 个字符BBB。一为.一为[[:alnum:]]

,要匹配直到下一个之后的所有字母数字字符,,您需要使用量词:[[:alnum:]]+

于 2013-10-04T07:20:09.670 回答