我正在尝试编写一个方法来扫描字符串中的某些字符,然后报告找到了哪些字符(如果有的话):
// Special characters are ~, #, @, and *
// If text == "Hello~Clarice, you're s#o ambitious", then this
// method should return a string == "~#". If no special characters
// found, return null. If the same special character occurs 2+ times,
// ignore it and do not return strings with duplicate special chars, like
// "##@***", etc. --> just "#@*".
public String detectAndGetSpecialCharacters(String text) {
Pattern p = Pattern.compile("[~#@*]");
Matcher m = pattern.matcher(text);
String specialCharactersFound = null;
if(m.find()) {
// ???
}
return specialCharactersFound;
}
我已经完成了此方法的 detect 部分,但我很难找到一种有效/优雅的方式来使用Matcher
告诉我哪个发现了特殊字符,并且将它们连接在一起(删除重复!)并返回它们。提前谢谢!
答案 0 :(得分:4)
为什么不简单地使用String.indexOf(specialChar)
。如果结果为> = 0,则为每个特殊字符调用此方法,这意味着特殊字符至少存在一次。
然后根据找到的索引对特殊字符进行排序,以构建重新排列的字符串。
不是很优雅,但我认为这很有效,因为:
编辑(这是示例代码)
private static class SpecialChar implements Comparable<SpecialChar>{
Integer position;
char c;
private SpecialChar(char c, Integer position) {
this.c = c;
this.position = position;
}
@Override
public int compareTo(SpecialChar another) {
return position.compareTo(another.position);
}
}
public static void main(String[] args){
String input = args[0];
char[] specialsChars = new char[]{'*','@','~','#'};
List<SpecialChar> results = new ArrayList<SpecialChar>();
for(char c:specialsChars){
int position = input.indexOf(c);
if(position>-1)results.add(new SpecialChar(c,position));
}
Collections.sort(results);
StringBuilder builder = new StringBuilder();
for(SpecialChar sp:results){
builder.append(sp.c);
}
System.out.print(builder.toString());
}
答案 1 :(得分:2)
您可以使用StringBuilder
,而不是使用字符串,并将每个匹配的字符附加到它,如果它不存在: -
StringBuilder builder = new StringBuilder();
while (m.find()) {
String str = m.group();
if (!builder.toString().contains(str)) {
builder.append(str);
}
}
// And finally
return builder.toString();
另一种方法是维护Set<String>
,并继续为其添加匹配的字符。它会自动删除重复项。然后,您可以使用Apache Commons StringUtils#join()
方法合并Set
的值以形成String
。或者您可以简单地遍历Set
并将每个字符串附加到StringBuilder
对象。无论你喜欢什么样的方式都适合。
答案 2 :(得分:0)
您需要capturing-group。用括号括起你的正则表达式,并为每个matcher#find
得到它。它将类似于:
public String detectAndGetSpecialCharacters(String text) {
Pattern p = Pattern.compile("([~#@*])");
Matcher m = pattern.matcher(text);
Set<String> specialCharacters = new HashSet<String>();
if (m.find()) {
specialCharacters.add(m.group(1));
}
StringBuilder specialCharactersFound = new StringBuilder();
for (String specialChar : specialCharacters) {
specialCharactersFound.append(specialChar);
}
return specialCharactersFound.toString();
}
添加到Set
将删除重复项,并在最后使用特殊字符构建String。并且它不会返回null,这通常不是一件好事。
修改强>
您实际上并不需要捕获组,因为您的正则表达式只获取特殊字符。你可以使用Matcher#group
。但是,学习更多东西是件好事;)