如何在正则表达式中执行此操作 - 代码库更改

时间:2011-07-24 12:08:03

标签: java regex

我有一个完整的基于Java的代码库,其成员名称为:

String m_sFoo;
Array m_arrKeepThings;

变量/对象名称包括用于表示成员的m_前缀和匈牙利表示法类型指示符。

我正在寻找一种方法来执行单次代码替换(例如上面的案例):

Array keepThings;
String foo;

当然还有很多其他选择,但我希望基于两个例子,我将能够完成全部变更。 性能不是问题,因为它是一次性修复。

澄清一下,如果我必须按行说明,那就是:

  1. 匹配以m_ [a-zA-Z]开头的单词。
  2. 在m_之后,丢弃第一个大写字母之前的所有内容。
  3. 将第一个大写字母更改为小写

3 个答案:

答案 0 :(得分:1)

如果你确实如此,那么确定提议的更改不会导致冲突(只有前缀不同的变量)我会用一行perl来做:

perl -pi.bak -e "s/\bm_[a-z_]+([A-Z]\w*)\b/this.\u$1/g;" *.java

这将执行Java源代码的内联编辑,同时保留带有扩展名.bak的备份替换字词边界之间的模式(\b),将替换的第一个字母大写({{1} })每行多次。

然后,您可以在备份文件和结果文件之间执行差异,以查看是否一切顺利。

答案 1 :(得分:1)

查看此帖子:Regex to change to sentence case

一般来说,我担心你不能用正则表达式改变字母的大小写。 我建议你实现一个简单的实用程序(使用你想要的任何语言)。你可以用java做到这一点。只需浏览文件树,搜索m_[sidc]([A-Z])之类的模式,获取捕获的序列,调用toLowerCase()并执行替换。

其他解决方案是使用eclipse搜索和替换m_sA,然后m_sB,... m_sZ。总计:26次。它有点愚蠢,但可能比实现和调试自己的代码更快。

答案 2 :(得分:0)

这是一些有效的Java代码。它不是纯粹的正则表达式,而是基于:

<强>用法:

String str = "String m_sFoo;\n"
        + "Array m_arrKeepThings;\n"
        + "List<? extends Reader> m_lstReaders; // A silly comment\n"
        + "String.format(\"Hello World!\"); /* No m_named vars here */";
// Read the file you want to handle instead

NameMatcher nm = new NameMatcher(str);
System.out.println(nm.performReplacements());

<强> NameMatcher.java

package so_6806699;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 *
 * @author martijn
 */
public class NameMatcher
{

    private String input;
    public static final String REGEX = "m_[a-z]+([A-Z0-9_\\$\\µ\\£]*)";
    public static final Pattern PATTERN = Pattern.compile(REGEX);

    public NameMatcher(String input)
    {
        this.input = input;
    }

    public String performReplacements()
    {
        Matcher m = PATTERN.matcher(input);
        StringBuilder sb = new StringBuilder();

        int oldEnd = 0;
        while (m.find())
        {
            int start = m.start();
            int end = m.end();

            String match = input.substring(start, end);
            String matchGroup1 = match.replaceAll(REGEX, "$1");
            if (!matchGroup1.isEmpty())
            {
                char[] match_array = matchGroup1.toCharArray();
                match_array[0] = Character.toLowerCase(match_array[0]);
                match = new String(match_array);
            }

            sb.append(input.substring(oldEnd, start));
            oldEnd = end;

            sb.append(match);
        }
        sb.append(input.substring(oldEnd));
        return sb.toString();
    }
}

演示输出

String foo;
Array keepThings;
List<? extends Reader> readers; // A silly comment
String.format("Hello World!"); /* No m_named vars here */

编辑0 : 由于美元符号($),micro(µ)和pound(£)是Java名称变量的有效字符,因此我编辑了正则表达式。

编辑1:似乎有很多非拉丁字符有效(éùàçè等)。希望你不必处理它们。

编辑2:我只是一个人!因此请注意代码中可能存在的错误! 首先进行备份!

编辑3:代码已改进。当代码包含此内容时,会抛出NPE:m_foo。这些将是未处理的。