标点符号的正则表达式

33

我完全不了解正则表达式,我正在尝试使用Java的java.util.regex来查找输入字符串中的标点符号。我事先不知道会得到什么样的标点符号,除了(1) !, ?, ., ...都是有效的标点符号,以及 (2) "<"和">"具有特殊含义,不算作标点符号。

程序本身会伪随机地构建短语,我想在该过程中将句子末尾的标点符号去掉。

我可以使用任何标点符号匹配整个单词,但是匹配程序只会给出该单词的索引。换言之:

Pattern p = Pattern.compile("(.*\\!)*?");
Matcher m = p.matcher([some input string]);

将获取任何以"!"结尾的单词。例如:

String inputString = "It is a warm Summer day!";
Pattern p = Pattern.compile("(.*\\!)*?");
Matcher m = p.matcher(inputString);
String match = inputString.substring(m.start(), m.end());

结果是 --> 字符串匹配 ~ "day!"

但是我想让Matcher仅索引"!",这样我就可以把它分开。

我可能可以针对可能获得的每种标点制作案例,并使用String.substring(...),但我希望在正则表达式的使用中存在某些错误来完成此操作。


哦!天啊,我甚至没有注意到。这完全不是故意的 - 谢谢你提出来! - Mister R2
4个回答

46

Java支持POSIX字符类的方式比较抽象。对于标点字符,Java中相当于[:punct:]的是\p{Punct}

请参阅以下链接了解详情。

这里有一个具体、可行的示例,其中使用了注释中的表达式。

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class RegexFindPunctuation {

    public static void main(String[] args) {
        Pattern p = Pattern.compile("\\p{Punct}");

        Matcher m = p.matcher("One day! when I was walking. I found your pants? just kidding...");
        int count = 0;
        while (m.find()) {
            count++;
            System.out.println("\nMatch number: " + count);
            System.out.println("start() : " + m.start());
            System.out.println("end()   : " + m.end());
            System.out.println("group() : " + m.group());
        }
    }
}

我尝试运行Pattern.compile("\p{Punct}")(遵循您提供的链接中提到的双重转义),但它也找不到任何标点符号。 具体来说,我运行了以下代码: String input = "One day! when I was walking. I found your pants? just kidding..."; Pattern p = Pattern.compile("\p{Punct}"); Matcher m = p.matcher(input); - Mister R2
2
与上述问题相同,使用Matcher.find()。请注意,这种方法在(内存)性能方面要比返回所有匹配项好得多。顺便说一下,如果您只想匹配整个字符串,也可以编写"input".matches("pattern") - Maarten Bodewes

27

我会尝试使用类字符正则表达式,类似于

"[.!?\\-]"

[]中添加任何您想匹配的字符。请注意转义可能对正则表达式解析器具有特殊含义的任何字符。

然后使用Matcher.find()迭代匹配,直到返回false。


7
提示:在这里可以了解到,字符类中的特殊字符或元字符包括右方括号 (])、反斜杠 ()、脱字符 (^) 和连字符 (-)。通常的元字符在字符类内部被视为普通字符。因此,"[\.\!\?]"与"[.!?]"相同。 - Pshemo
4
@Pshemo: 你在评论中忘记转义反斜杠字符了 :) - Maarten Bodewes
1
@owlstead 我看到了,但是已经太晚去编辑了,创建新的评论来纠正也没有意义,因为上下文和链接足以说明应该在括号中放什么 :D。 - Pshemo
1
整个字符串不匹配,因此您必须使用Matcher.find(),将其添加到答案中。匹配的字符串是group()group(0),应包含单个标点符号。 - Maarten Bodewes
1
@cliffclof 我认为不是。这更多是一个正则表达式语法问题,而不是Java问题。[]内的特殊字符会自动转义,除非它们在该上下文中具有特殊含义。 - Code-Apprentice
显示剩余7条评论

1

我会尝试

\W

它匹配任何非单词字符。这包括空格和标点符号,但不包括下划线。它等同于 [^A-Za-z0-9_]。


很遗憾,这样做行不通 - OP想要一个正则表达式,它不会排除某些非标点符号,如<和>。 - Bill Horvath
括号,例如“(”和“)”,也被视为标点符号。 - Klaws

0
我试图找到如何替换正则表达式,同时保留其他正则表达式部分的方法。 例如:Hi , how are you ? -> Hi, how are you?。 经过一番研究,我发现可以使用“()”创建组,因此只需替换第一个组,即“(\s)”即可。
        String a = "Hi , how are you ?";
        String p = "(\s)([,.!?\\-])";
        System.out.println(a.replaceAll(p,"$2"));
        //output: Hi, how are you?

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接