如何在java中替换匹配的字符串?

时间:2015-11-17 14:56:50

标签: java java-io

我有一个关于如何在找到匹配字符时替换String的问题。在这种情况下,我读取包含用下划线标记的变量的java文件。这里是java文件:

 public int[][] initArray(int rows, int cols, int init_value)
{
 int[][] _bb = (int[][])null;
 if ((rows > 1) && (cols > 1)) {
   _bb = new int[rows][cols];
   for (int _ii = 0; _ii < rows; _ii++) {
     for (int _ee = 0; _ee < cols; _ee++) {
       _bb[_ii][_ee] = init_value;
     }
   }
 } else {
   warning("Array length must be greater than zero!");
 }
 return _bb;
}

包含下划线的所有变量都将替换为generate string。那么,这是我用来读取该文件并替换匹配字符串的代码:

HashMap<String, String> map = new HashMap<String, String>();

if (line.contains(" _") && line.contains(";")) {

    String get = varname(line);

    RandomString r = new RandomString();

    String[] split = get.split("\\s+");
    String gvarname = split[0];

   ss = "_"+gvarname;
   map.put(ss, "l"+r.generateRandomString());

   for(String key: map.keySet()){
       if(line.contains(key)){
           line = line.replace(key, map.get(key));

       }
   }

然后,这是一个获取变量名索引的方法:

String varname(String str){
    int startIdx = str.indexOf("_");
    int endIdx = str.indexOf(';');

    String content = str.substring(startIdx + 1, endIdx);
    return content;
}

实际上上面的代码正在工作并替换一些变量名称,但是当我放置空格示例_bb [_ii]不起作用时,某些字符标记匹配,但_bb [_ii]正在工作。我不知道怎么样,救救我!

由于

2 个答案:

答案 0 :(得分:0)

在您的第一个if语句中,检查字符串是否包含" _"(带有前导空格的下划线)。

如果在source-java-file的以下行中

       _bb[_ii][_ee] = init_value;

_bb...使用制表符进行缩进,<tab>_bb<space>_bb不匹配。 _ii_ee之前没有前导空格,因此if会返回false

如果您在[_ii之间添加了空格,则会找到<space>_ii的匹配项以及if的{​​{1}}结果并执行替换代码

如果您确定源文本中除了作为替换指示符之外不会使用下划线,则只需从if条件中删除空格并改为使用true

顺便说一句:您确定要检查该行是否必须包含line.contains("_")吗?如果您的源文本包含;

之类的行,该怎么办?

另外,因为

while(_xx==true) {

您的代码无法正确分割String[] split = get.split("\\s+"); String gvarname = split[0]; 之类的行(即使它是{,由于_bb[_ii][_ee],您只会替换您找到的第一个标识符,后续的标识符会被忽略) 。您的拆分搜索空格和源代码行不包含任何内容。同样,您可以更改此选项并拆分下划线(这将返回包含split[0]bb[ii][的数组,然后循环每个返回的数组元素,直到找到第一个字符为止不能成为变量标识符的一部分(例如,直到第一个非字母数字字符)。

ee]加上数组元素的部分直到该非字母数字字符,然后是您要替换的标识符。

答案 1 :(得分:0)

使用正则表达式识别整个变量,此处使用\b查找字边界。

public class Obfuscate {

    private static final Pattern VAR_PATTERN = Pattern.compile("\\b_(\\w+)\\b");
    private final Map<String, String> renames = new HashMap<>();

    public String obfuscate(String sourceCode) {
        StringBuffer buf = new StringBuffer(sourceCode.length() + 100);
        Matcher m = VAR_PATTERN.matcher(sourceCode);
        while (m.find()) {
            String var = m.group(1);
            String newVar = renames.get(var);
            if (newVar == null) {
                newVar = randomVar();
                renames.put(var, newVar);
            }
            m.appendReplacement(buf, newVar);
        }
        m.appendTail(buf);
        return buf.toString();
    }
}

需要使用地图将相同的旧变量与相同的新名称匹配。

可能需要Set<String>个新名称来检查生成的名称是否重复。

你做同一个var的replaceAll的方法也很好,但需要全部阅读。可以重复上述方法(例如每行),因此将地图作为字段。