有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

Java正则表达式到正则表达式以删除双连字符并保留单连字符

所以我需要一个正则表达式,它可以从文本中删除所有非单词字符(空格和连字符除外),这样我就可以计算文本中的单词数。 差不多

String().replaceAll("[^\\p{L}+(?:\\-\n?\\p{L}+)* ]", "")

大多数情况下都有效,因为它保留连字符的单词,但当我使用双连字符时,问题就出现了。美式英语中的双连字符应该代表一个破折号,所以在我的例子中,我也需要用空格来代替它。有人知道如何修改它以避免这种情况发生吗

这里有一个例子。以下一句:

当我离开校园时,我把所有的东西都丢了——钱包,钥匙,所有的东西

在正则表达式之后应该是这样的:

当我离开校园时,我丢失了所有的东西钱包钥匙一切

编辑-我对使用两个replaceAlls不感兴趣,我想在一个正则表达式中进行编辑


共 (1) 个答案

  1. # 1 楼答案

    原始正则表达式已损坏,因为(?:...)*+在字符类[]内被视为文字字符

    在Java的字符类中,[]\(用于转义序列和属性),\Q\E(用于引用字符类中的特殊字符),^(仅在类的开头有效),-(在两个字符之间有效),&&(用于字符类交叉)是唯一具有特殊含义的字符/序列

    您可以根据这个示例字符串测试您的正则表达式,以确认我上面所说的

    This is another example: (parentheses) + [brackets] + (asterisks *)

    您可以直接将单词与此正则表达式(正则表达式字符类中的部分)匹配,而不是删除无效字符和填充:

    "\\p{L}+(?:-\n?\\p{L}+)*"
    

    上面的正则表达式可在Matcher循环中用于计算字数:

    Pattern p = Pattern.compile("\\p{L}+(?:-\n?\\p{L}+)*");
    Matcher m = p.matcher(input);
    int count = 0;
    
    while (m.find()) {
       count++;
    }
    

    如果仍要替换与上述正则表达式中定义的“单词”定义不匹配的所有字符:

    input.replaceAll("(?s).*?(\\p{L}+(?:-\n?\\p{L}+)*)|.+", "$1 ");
    

    (?s).*?(\\p{L}+(?:-\n?\\p{L}+)*)在“单词”之前搜索非“单词”字符,并删除它们,在“单词”之后添加空格。末尾的.+处理字符串末尾的非“单词”字符序列

    请注意,如果最后一个字符不是“单词”的一部分,它将产生一个尾随空格

    Demo on regex101

    测试输入:

    While I was off-campus, I lost all my belongings wallet, keys, everything!
    
    This is another example: (parentheses) + [brackets] + (asterisks *)
    
    Along-
    longl-
    onglo-
    ngword!
    

    测试输出(注意末尾的尾随空格):

    While I was off-campus I lost all my belongings wallet keys everything This is another example parentheses brackets asterisks Along- longl- onglo- ngword 
    

    如果你问我是否可以通过修改上面的正则表达式来消除尾随空格,我会说在Java中不可能。这里的问题是 必须替换为分隔2个“单词”的空格,而其他非“单词”字符必须替换为空字符串