简体   繁体   English

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

[英]How to replace matched character String in java?

I have a question about how to replace String when matched character found. 我有一个关于找到匹配字符时如何替换String的问题。 In this case, i read java file that contains variable which marked with underscore. 在这种情况下,我读取了包含带有下划线标记的变量的java文件。 Here the java file: 这里的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;
}

All of variable that contain underscore will be replaced with generate string. 包含下划线的所有变量都将替换为generate string。 Well, then this is the code that i have used to read that file and replace matched 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));

       }
   }

Then, this is a method to get an index of variable name: 然后,这是一种获取变量名称索引的方法:

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

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

Actually above code is working and replace some variables name, but some character noted matched when i put space example _bb[_ii] is not working, but _bb[ _ii ] is working. 实际上,上面的代码可以正常工作并替换一些变量名称,但是当我放空格示例_bb [_ii]不起作用而_bb [_ii]起作用时,注意到某些字符匹配。 I don't know how, help me! 我不知道如何,帮帮我!

Thanks 谢谢

In your first if -statement you check if the string contains " _" (an underscore with a leading space). 在您的第一个if -statement中,检查字符串是否包含" _" (带下划线的下划线)。

If in the following line of your source-java-file 如果在您的source-java-file的以下行中

       _bb[_ii][_ee] = init_value;

_bb... is indented with tabulators, <tab>_bb will not match <space>_bb . _bb...用制表符缩进, <tab>_bb<space>_bb不匹配。 There is no leading space before _ii and _ee either, so the if returns false . _ii_ee之前也没有前导空格,因此if返回false

If you put a space between [ and _ii , you find a match for <space>_ii and your if results in true and executes your replacement code. 如果在[_ii之间放置一个空格,则会找到<space>_ii的匹配项,并且if结果为true并执行您的替换代码。

If you are sure that there will be no other use of an underscore in your source text other than as a replacement indicator, you can simply remove the space from your if-condition and use line.contains("_") instead. 如果您确定除了作为替换指示符之外,在源文本中将没有其他下划线的使用,则可以简单地从if条件中删除空格,而使用line.contains("_")

Btw: Are you sure that you want to check that the line must contain a ; 顺便说一句:您确定要检查该行必须包含;; aswell? 藏汉? What if your source text contains a line like while(_xx==true) { ? 如果您的源文本包含while(_xx==true) {怎么办?

Also, because of 另外,由于

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

your code is not able to split a line like _bb[_ii][_ee] correctly (and even if it would be, because of split[0] you would only replace the first identifier you found, subsequent ones would be ignored). 您的代码无法正确分割_bb[_ii][_ee] (即使那样,由于split[0]您也只能替换找到的第一个标识符,后续的标识符将被忽略)。 Your split searches for spaces and the source line doesn't contain any. 您的拆分将搜索空格,并且源代码行不包含任何空格。 Again, you could probably change this and split for underscores (this would return an array containing bb[ , ii][ and ee] ) and then loop every returned array element until you find the first character that can't be part of your variable identifier (eg until the first non-alphanumeric character). 再次,您可能可以更改此值并拆分为下划线(这将返回包含bb[ii][ee]数组),然后循环返回的每个数组元素,直到找到不能成为变量一部分的第一个字符标识符(例如,直到第一个非字母数字字符)。

An _ plus the part of the array element up to that non-alphanumeric character is then the identifier that you want to replace. _加上数组元素中直到该非字母数字字符的部分就是要替换的标识符。

Use regex to recognize the entire variable, here using \\b to find word boundaries. 使用正则表达式识别整个变量,此处使用\\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();
    }
}

A map is needed to match the same old variable to the same new name. 需要一个映射,以将相同的旧变量与相同的新名称进行匹配。

A Set<String> of new names might be needed to check that the generated name does not repeat. 可能需要使用新名称的Set<String>来检查生成的名称是否重复。

Your approach of doing a replaceAll of the same var is fine too, but requires reading all. 您执行相同的var的replaceAll的方法也很好,但是需要全部读取。 The method above can be repeated (say per line), hence the map as field. 可以重复上述方法(例如每行),因此将地图作为字段。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM