我已从源中提取数据,现在它是一组令牌。这些标记在结尾或有时在开头包含垃圾字符或特殊字符。例如,我有以下设置。
此数据应分别如下...
为净化此字符串集,我实现了以下方法,该方法正常工作。 See on regex101.com...
public Filter filterSpecialCharacters() {
String regex = "^([^a-z0-9A-Z]*)([a-z0-9A-Z])(.*)([a-z0-9A-Z])([^a-z0-9A-Z]*)$";
set = set
.stream()
.map(str -> str.replaceAll(regex, "$2$3$4"))
.collect(Collectors.toSet());
return this;
}
但是我对正在使用的正则表达式仍然不满意,因为我拥有大量数据。想看看是否有更好的选择。
答案 0 :(得分:2)
我想使用\p{Punct}
删除所有这些标点符号!"#$%&'()*+,-./:;<=>?@[\]^_
{|}〜`
String regex = "^\\p{Punct}*([a-z0-9A-Z -]*)\\p{Punct}*$";
set = set.stream()
.map(str -> str.replaceAll(regex, "$1"))
.collect(Collectors.toSet());
=>[synthetic, devices, traffic-calming, manufactured traffic , artificial turf]
看看这个Summary of regular-expression constructs
或者像在评论中@Ted Hopp提到的那样,您可以使用两张地图,其中一张从乞讨中删除特殊字符,第二张从结尾删除它们:
set = set.stream()
.map(str -> str.replaceFirst("^[^a-z0-9A-Z]*", ""))
.map(str -> str.replaceFirst("[^a-z0-9A-Z]*$", ""))
.collect(Collectors.toSet());
答案 1 :(得分:1)
您可以在单个被动正则表达式中执行此操作,每次操作都相同。
全局查找(?m)^[^a-z0-9A-Z\r\n]*(.*?)[^a-z0-9A-Z\r\n]*$
替换$1
https://regex101.com/r/tGFbLm/1
(?m) # Multi-line mode
^ # BOL
[^a-z0-9A-Z\r\n]*
( .*? ) # (1), Passive content to write back
[^a-z0-9A-Z\r\n]*
$ # EOL
答案 2 :(得分:0)
请勿将正则表达式用于此类简单修饰。解析字符串并修剪它。代码很大,但是肯定比正则表达式快。
public static List<String> filterSpecialCharacters(List<String> input) {
Iterator<String> it = input.iterator();
List<String> output = new ArrayList<String>();
// For all strings in the List
while (it.hasNext()) {
String s = it.next();
int endIndex = s.length() - 1;
// Get the last index of alpha numeric char
for (int i = endIndex; i >= 0; i--) {
if (isAlphaNumeric(s.charAt(i))) {
endIndex = i;
break;
}
}
StringBuilder out = new StringBuilder();
boolean startCopying = false;
// Parse the string till the last index of alpha numeric char
for (int i = 0; i <= endIndex; i++) {
// Ignore the leading occurrences non alpha-num chars
if (!startCopying && !isAlphaNumeric(s.charAt(i))) {
continue;
}
// Start copying to output buffer after(including) the first occurrence of alpha-num char
else {
startCopying = true;
out.append(s.charAt(i));
}
}
// Add the trimmed string to the output list.
output.add(out.toString());
}
return output;
}
// Updated this method with the characters that you dont want to trim
private static boolean isAlphaNumeric(char c) {
return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9');
}
请测试此代码以查看其是否满足您的条件。我看到这几乎比正则表达式修整快10倍(在其他答案中使用)。
另外,如果性能对您很重要,则建议您使用Iterator
来解析Set
,而不要使用stream/map/collect
函数。