如何替换java中匹配的字符串?
How to replace matched character String in 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;
}
实际上上面的代码正在工作并替换了一些变量名称,但是当我把 space 示例 _bb[_ii] 不起作用时,一些字符被记录匹配,但是 _bb[_ii] 正在工作。不知道怎么办,求助!
谢谢
在您的第一个 if
语句中,您检查字符串是否包含 " _"
(带前导 space 的下划线)。
如果在你源码的下一行-java-文件
_bb[_ii][_ee] = init_value;
_bb...
用制表符缩进,<tab>_bb
不会匹配<space>_bb
。在 _ii
和 _ee
之前也没有前导 space,所以 if
returns false
.
如果您在 [
和 _ii
之间放置一个 space,您会找到 <space>_ii
的匹配项,并且您的 if
结果为 true
并执行您的替换代码。
如果您确定在您的源文本中除了作为替换指示符之外不会有其他用途的下划线,您可以简单地从您的 if 条件中删除 space 并使用 line.contains("_")
代替。
顺便说一句:您确定要检查该行是否也必须包含 ;
?如果您的源文本包含像 while(_xx==true) {
?
这样的行怎么办
另外,由于
String[] split = get.split("\s+");
String gvarname = split[0];
您的代码无法正确拆分 _bb[_ii][_ee]
之类的行(即使可以,因为 split[0]
您只会替换找到的第一个标识符,后续的标识符将是忽略)。您的拆分搜索 spaces 并且源代码行不包含任何内容。同样,您可能会更改它并拆分为下划线(这将 return 一个包含 bb[
、ii][
和 ee]
的数组)然后循环每个 returned数组元素,直到找到不能成为变量标识符一部分的第一个字符(例如,直到第一个非字母数字字符)。
_
加上数组元素直到该非字母数字字符的部分就是您要替换的标识符。
使用正则表达式识别整个变量,这里使用\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>
个新名称来检查生成的名称是否重复。
您对同一变量执行 replaceAll
的方法也很好,但需要全部阅读。上面的方法可以重复(比如每行),因此地图作为字段。
我有一个关于在找到匹配字符时如何替换字符串的问题。在这种情况下,我读取了 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;
}
实际上上面的代码正在工作并替换了一些变量名称,但是当我把 space 示例 _bb[_ii] 不起作用时,一些字符被记录匹配,但是 _bb[_ii] 正在工作。不知道怎么办,求助!
谢谢
在您的第一个 if
语句中,您检查字符串是否包含 " _"
(带前导 space 的下划线)。
如果在你源码的下一行-java-文件
_bb[_ii][_ee] = init_value;
_bb...
用制表符缩进,<tab>_bb
不会匹配<space>_bb
。在 _ii
和 _ee
之前也没有前导 space,所以 if
returns false
.
如果您在 [
和 _ii
之间放置一个 space,您会找到 <space>_ii
的匹配项,并且您的 if
结果为 true
并执行您的替换代码。
如果您确定在您的源文本中除了作为替换指示符之外不会有其他用途的下划线,您可以简单地从您的 if 条件中删除 space 并使用 line.contains("_")
代替。
顺便说一句:您确定要检查该行是否也必须包含 ;
?如果您的源文本包含像 while(_xx==true) {
?
另外,由于
String[] split = get.split("\s+");
String gvarname = split[0];
您的代码无法正确拆分 _bb[_ii][_ee]
之类的行(即使可以,因为 split[0]
您只会替换找到的第一个标识符,后续的标识符将是忽略)。您的拆分搜索 spaces 并且源代码行不包含任何内容。同样,您可能会更改它并拆分为下划线(这将 return 一个包含 bb[
、ii][
和 ee]
的数组)然后循环每个 returned数组元素,直到找到不能成为变量标识符一部分的第一个字符(例如,直到第一个非字母数字字符)。
_
加上数组元素直到该非字母数字字符的部分就是您要替换的标识符。
使用正则表达式识别整个变量,这里使用\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>
个新名称来检查生成的名称是否重复。
您对同一变量执行 replaceAll
的方法也很好,但需要全部阅读。上面的方法可以重复(比如每行),因此地图作为字段。