我有一个关于如何在找到匹配字符时替换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]正在工作。我不知道怎么样,救救我!
由于
答案 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
的方法也很好,但需要全部阅读。可以重复上述方法(例如每行),因此将地图作为字段。