正则表达式方言:Java
问题:给定一个字符串,替换其中出现的所有子字符串,除非这些出现在引号内。
示例 1:
string: "test substr 'test substr' substr"
substring: "substr"
replacement: "YYYY"
output: "test YYYY 'test substr' YYYY"
例子2:
string: "test sstr 'test sstr' sstr"
substring: "substr"
replacement: "YYYY"
output: "test sstr 'test sstr' sstr"
示例 3:
string: "test 'test substr'"
substring: "substr"
replacement: "YYYY"
output: "test 'test substr'"
这是我迄今为止最好的尝试:
Regex: ((?:[^']*'[^']+')*?[^']*?)substring
Replace: $1replacement
它的问题是它需要在引号内的最后一个字符串之后的引号外的子字符串,否则它不起作用,因此 Example3 将失败(输出:“test 'test YYYY'”)。
非常感谢您的帮助。
最佳答案
这里有一个方法:
public class Main {
public static void main(String [] args) {
String[] tests = {
"test substr 'test substr' substr",
"test sstr 'test sstr' sstr",
"test 'test substr'"
};
String regex = "substr(?=([^']*'[^']*')*[^']*$)";
for(String t : tests) {
System.out.println(t.replaceAll(regex, "YYYY"));
}
}
}
打印:
test YYYY 'test substr' YYYY test sstr 'test sstr' sstr test 'test substr'
Note that this does not work if '
can be escaped with a \
for example.
A quick explanation:
The following: ([^']*'[^']*')*
will match 0 or an even number of single quotes with non quotes in between, and [^']*$
matches any non-quotes and the end-of-string.
So, the complete regex substr(?=([^']*'[^']*')*[^']*$)
matches any "substr"
that has 0 or an even number of single quotes ahead of it, when looking all the way to the end-of-string!
Looking all the way to the end-of-string is the key here. If you wouldn't do that, the following "substr"
would also be replaced:
aaa 'substr' bbb 'ccc ddd' eee
^ ^ ^
| | |
i ii iii
因为它“看到”前面有偶数个单引号(i 和 ii)。您必须强制它查看其右侧的整个字符串(一直到 $
)!
关于java - 替换字符串中的子字符串,除非字符串在引号内,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6775662/