有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

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

我有一个关于找到匹配字符时如何替换字符串的问题。在本例中,我读取了包含用下划线标记的变量的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;
}

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

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) 个答案

  1. # 1 楼答案

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

    如果在源java文件的以下行中

           _bb[_ii][_ee] = init_value;
    

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

    如果在[_ii之间放置一个空格,则会找到<space>_ii的匹配项,并且if会产生true并执行替换代码

    如果您确定在源文本中除了用作替换指示符之外,不会使用下划线,那么只需从If条件中删除空格,然后使用line.contains("_")

    顺便说一句:你确定要检查行也必须包含;吗?如果源文本包含while(_xx==true) {这样的行怎么办

    还有,因为

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

    您的代码无法正确拆分像_bb[_ii][_ee]这样的行(即使是这样,因为split[0]您只会替换找到的第一个标识符,后续的标识符也会被忽略)。分割搜索空格,而源行不包含任何空格。同样,您可能会更改此项并拆分为下划线(这将返回一个包含bb[ii][ee]的数组),然后循环每个返回的数组元素,直到找到不能作为变量标识符一部分的第一个字符(例如,直到第一个非字母数字字符)

    然后,一个_加上数组元素中直到该非字母数字字符的部分就是要替换的标识符

  2. # 2 楼答案

    使用regex识别整个变量,这里使用\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的方法也很好,但需要全部读取。上面的方法可以重复(比如每行),因此映射为字段