正则表达式和逃脱和未转义的分隔符
与此相关的问题
我有一个字符串
a\;b\\;c;d
在Java中看起来像
String s = "a\\;b\\\\;c;d"
我需要用分号按照以下规则拆分它:
-
如果分号前面有反斜杠,则不应将其视为分隔符(在a和b之间)。
-
如果反斜杠本身被转义,因此不会以分号方式转义,那么分号应该是分隔符(在b和c之间)。
因此,如果在它之前存在零或偶数个反斜杠,则应将分号视为分隔符。
例如上面,我想得到以下字符串(java编译器的双反斜杠):
a\;b\\ c d
你可以使用正则表达式
(?:\\.|[^;\\]++)*
匹配未转义分号之间的所有文本:
List matchList = new ArrayList (); try { Pattern regex = Pattern.compile("(?:\\\\.|[^;\\\\]++)*"); Matcher regexMatcher = regex.matcher(subjectString); while (regexMatcher.find()) { matchList.add(regexMatcher.group()); }
说明:
(?: # Match either... \\. # any escaped character | # or... [^;\\]++ # any character(s) except semicolon or backslash; possessive match )* # Repeat any number of times.
由于嵌套量词,占有性匹配( ++
)对于避免灾难性回溯非常重要。
String[] splitArray = subjectString.split("(?
这应该工作。
说明:
// (?
所以你只需匹配前面没有前面的分号。
编辑:
String[] splitArray = subjectString.split("(?
这将照顾任何奇数。 如果你的数量超过4000000,它当然会失败。 编辑答案的说明:
// (?
我不相信用任何正则表达式来检测这些案例。 我通常会为这样的事情做一个简单的循环,我会用C
描绘它,因为它很久以前我最后一次触及Java
😉
int i, len, state; char c; for (len=myString.size(), state=0, i=0; i < len; i++) { c=myString[i]; if (state == 0) { if (c == '\\') { state++; } else if (c == ';') { printf("; at offset %d", i); } } else { state--; } }
优点是:
- 您可以在每个步骤上执行语义操作。
- 把它移植到另一种语言很容易。
- 您不需要为这个简单的任务包含完整的正则表达式库,这增加了可移植性。
- 它应该比正则表达式匹配器快很多。
此方法假定您的字符串在字符串中不具有char '\0'
。 如果你这样做,你可以使用其他一些char。
public static String[] split(String s) { String[] result = s.replaceAll("([^\\\\])\\\\;", "$1\0").split(";"); for (int i = 0; i < result.length; i++) { result[i] = result[i].replaceAll("\0", "\\\\;"); } return result; }
这是我认为的真正答案。 在我的情况下,我试图分裂使用|
和转义字符是&
。
final String regx = "(?
|e|”.split(regx); System.out.println(Arrays.toString(res));
在这段代码中,我使用Lookbehind来逃避和角色。 请注意,背后的外观必须具有最大长度。
(?
这意味着任何|
除了那些((?:[^&]|^)(&&){0,10000}&))
,这部分意味着任何奇数的&
s。 部分(?:[^&]|^)
对于确保计算|
后面的所有&
s非常重要 到开头或其他一些角色。