与短语匹配的正则表达式,除非它已经加前缀

时间:2012-07-13 04:27:25

标签: regex sed

我正在清理一个大的C ++代码库,我需要将所有“vector”类型的变量更改为“std :: vector”。跳过代码中的#include和注释。最重要的是,如果表达式已经写成“std :: vector”,请不要将其转换为“std :: std :: vector”

那是:

#include <vector>
vector<Foo> foolist;
typedef vector<Foo> FooListType;
std::vector<Foo> otherfoolist;
int main()
{
    // this vector is for iteration
    for (vector <Foo>::iterator itor = foo.begin...)

转换为

#include <vector>
std::vector<Foo> foolist;
typedef std::vector<Foo> FooListType;
std::vector<Foo> otherfoolist;
int main()
{
    // this vector is for iteration
    for (std::vector<Foo>::iterator itor = foo.begin...)

到目前为止,我已将此范围缩小为两个sed命令

sed -r 's/vector\s{0,1}</std::vector</g' < codefile > tmpfile
sed 's/std::std/std/' < tmpfile > codefile

第一个sed匹配“vector&lt; and”vector&lt;“并转换为”std :: vector&lt;“。

第二个sed修复了转换“std :: vector&lt;”的副作用进入“std :: std :: vector&lt;”。

如何合并上面的两个不同的正则表达式,这样我就可以使用一个sed命令来正确修复代码。

我尝试过在线阅读前瞻和后视,但我的眼睛开始消失。

3 个答案:

答案 0 :(得分:3)

您可以使用

使第一个正则表达式与可能的std::匹配
sed -r 's/[std:]*vector\s{0,1}</std::vector</' < codefile > tmpfile

btw:您可以通过添加-i并将文件作为命令行参数传递来进行更改:

sed -i -r 's/[std:]*vector\s{0,1}</std::vector</' codefile

答案 1 :(得分:2)

这可能适合你(GNU sed):

sed -i 's/\(^\|[^<:]\)\(vector\s*<\)/\1std::\2/g' file

答案 2 :(得分:1)

如果您的sed版本不支持扩展正则表达式,则可以使用perl:

perl -lane ' if (!/^\s*#include/) {s!(?:std::)?vector!std::vector!g;} print; ' < codefile > tmpfile

这将适用于以下情况:vector<vector<Foo>> otherfoolist;

另请参阅此答案:https://stackoverflow.com/a/6157705/390913