正则表达式如何匹配一个单词存在一次或零次并且不占捕获组位置

我与影子孤独终老i 提交于 2019-11-30 02:21:09

正则表达式如何匹配一个单词存在一次零次并且不占捕获组位置

今天要用正则表达式实现匹配一个词出现一次或者不出现的情况,但是又不仅仅是这么简单的需求。先详细说下我这种情况吧,也许有人也遇到这种情况但是没找办法的时候可以参考一下。

前言

如果对正则表达式基本用法还不太熟悉的同学,可以参考下菜鸟教程上正则表达式的简单教程摸我直达

示例

例如打开一个应用。字符串可能是“open the qq”,“open qq”。“qq”是我想要得到的内容,但是这个“the”怎么办呢。

尝试一
一开始我是这么想的,把正则表达式写成这样“open the? ([A-Za-z]+[0-9]*)
显然这是不行的,不然我也不会写这博客了(刚开始用正则表达式,所以大家别笑我这样去试,哈哈),这样只会匹配“the”中的“e”。

尝试二
我又写了一个这样的“open (the)? ([A-Za-z]+[0-9]*)”,然后这样也是没办法满足我的需求的,因为这样我通过捕获组并不能正常的得到类似“qq”这样的应用名。因为“(the)?”也会被当成捕获组干扰结果。此时的我非常头大,怎么办呢怎么办呢。然后我又好好看了下菜鸟教程上正则表达式的各种语法。发现了下面这个语法。这简直就是专门为我这种情况准备的啊,既可以匹配单词,又能让他不占据捕获组的位置。
关键点

尝试三
然后我就进行了第三次尝试,正则表达式是这样的open (?:the)? ([A-Za-z]+[0-9]*)
忘了写我的测试代码了,加上

String regex = "open (?:the)? ([A-Za-z]+[0-9]*)";
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher("open the qq");
        if (matcher.find()) {
            System.out.println("find");
            int i = matcher.groupCount();
            System.out.println("i:" + i);
            for (int j = i; j <= i; j++) {
                System.out.println(matcher.group(j));
            }
        }

然后结果是可以的,终于可以了。
结果
然后我又试了下把输入从“open the qq”改成“open qq”
这里写图片描述
发生了啥,怎么又不行了,我该怎么办,然后我又仔细看了下自己写正则表达式,为了能够看的更加清晰,我上个图片。
这里写图片描述
红色框的地方是两空格字符,当我输入是“open qq”的时候,实际上中间只有一个空格字符,所以是无法与正则匹配的。然后我就把第二个空格改成了“\s?”,这次完整的正则就是
open (?:the)?\s?([A-Za-z]+[0-9]*)
这样不管是“open qq”还是“open the qq”,我都可以顺利得到“qq”这个应用名。

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!