我尝试将一个字符串拆分为标记.
令牌分隔符不是单个字符,某些分隔符包含在其他分隔符中(例如&和&&),我需要将分隔符作为标记返回.
StringTokenizer无法处理多个字符分隔符.我认为它可以使用String.split,但无法猜出适合我需要的神奇正则表达式.
任何的想法 ?
例:
Token delimiters: "&", "&&", "=", "=>", " "
String to tokenize: a & b&&c=>d
Expected result: an string array containing "a", " ", "&", " ", "b", "&&", "c", "=>", "d"
Run Code Online (Sandbox Code Playgroud)
---编辑---
感谢大家的帮助,Dasblinkenlight为我提供了解决方案.以下是我在他的帮助下写的"随时可用"代码:
private static String[] wonderfulTokenizer(String string, String[] delimiters) {
// First, create a regular expression that matches the union of the delimiters
// Be aware that, in case of delimiters containing others (example && and &),
// the longer may be before the shorter (&& should be before &) or the regexpr
// parser will recognize && as two &.
Arrays.sort(delimiters, new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
return -o1.compareTo(o2);
}
});
// Build a string that will contain the regular expression
StringBuilder regexpr = new StringBuilder();
regexpr.append('(');
for (String delim : delimiters) { // For each delimiter
if (regexpr.length() != 1) regexpr.append('|'); // Add union separator if needed
for (int i = 0; i < delim.length(); i++) {
// Add an escape character if the character is a regexp reserved char
regexpr.append('\\');
regexpr.append(delim.charAt(i));
}
}
regexpr.append(')'); // Close the union
Pattern p = Pattern.compile(regexpr.toString());
// Now, search for the tokens
List<String> res = new ArrayList<String>();
Matcher m = p.matcher(string);
int pos = 0;
while (m.find()) { // While there's a delimiter in the string
if (pos != m.start()) {
// If there's something between the current and the previous delimiter
// Add it to the tokens list
res.add(string.substring(pos, m.start()));
}
res.add(m.group()); // add the delimiter
pos = m.end(); // Remember end of delimiter
}
if (pos != string.length()) {
// If it remains some characters in the string after last delimiter
// Add this to the token list
res.add(string.substring(pos));
}
// Return the result
return res.toArray(new String[res.size()]);
}
Run Code Online (Sandbox Code Playgroud)
如果您通过仅创建一次Pattern来标记许多字符串,则可以进行优化.
您可以使用Pattern和一个简单的循环来实现您正在寻找的结果:
List<String> res = new ArrayList<String>();
Pattern p = Pattern.compile("([&]{1,2}|=>?| +)");
String s = "s=a&=>b";
Matcher m = p.matcher(s);
int pos = 0;
while (m.find()) {
if (pos != m.start()) {
res.add(s.substring(pos, m.start()));
}
res.add(m.group());
pos = m.end();
}
if (pos != s.length()) {
res.add(s.substring(pos));
}
for (String t : res) {
System.out.println("'"+t+"'");
}
Run Code Online (Sandbox Code Playgroud)
这会产生以下结果:
's'
'='
'a'
'&'
'=>'
'b'
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
9384 次 |
| 最近记录: |