繁体   English   中英

正则表达式可修剪给定字符串中的特殊字符

[英]Regex to trim special characters from the given string

我已经从源中提取了数据,现在它是一组令牌。 这些标记在结尾或有时在开头包含垃圾字符或特殊字符。 例如,我有以下设置。

  • 虚假交通
  • (设备
  • 流量调整)
  • 交通-
  • 合成的
  • 人造草坪。)

该数据应分别如下。

  • 虚假交通
  • 设备
  • 交通管制
  • 交通
  • 合成的
  • 人造草坪

为了净化此字符串集,我实现了以下方法,该方法正常工作。 参见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;
}

但是我仍然对使用的正则表达式不满意,因为我有大量的数据。 想看看是否有更好的选择。

我想使用\\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]

看一下这个正则表达式构造摘要


或像@Ted Hopp在评论中提到的那样,您可以使用两个地图,其中一个从乞讨中删除特殊字符,第二个从结尾删除它们:

set = set.stream()
        .map(str -> str.replaceFirst("^[^a-z0-9A-Z]*", ""))
        .map(str -> str.replaceFirst("[^a-z0-9A-Z]*$", ""))
        .collect(Collectors.toSet());

您可以在单个无源正则表达式中执行此操作,每次工作都相同。

全局查找(?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

对于此类简单修饰,请勿使用正则表达式。 解析字符串并修剪它。 代码很大,但是肯定比正则表达式快。

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函数。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM