Android 带有错误检查的正则表达式

Android 带有错误检查的正则表达式,android,regex,Android,Regex,我已经做了很多搜索,但是我对正则表达式和我的google fu很糟糕,在这个例子中,我的google fu并不强大 情景: 在推送通知中,我们收到一个包含9位内容ID的URL 示例URL:http://www.something.com/foo/bar/Some-title-Goes-here-123456789.html(123456789是此场景中的内容ID) 要分析内容ID的当前正则表达式: public String getContentIdFromPathAndQueryString(

我已经做了很多搜索,但是我对正则表达式和我的google fu很糟糕,在这个例子中,我的google fu并不强大

情景:

在推送通知中,我们收到一个包含9位内容ID的URL

示例URL:
http://www.something.com/foo/bar/Some-title-Goes-here-123456789.html
(123456789是此场景中的内容ID)

要分析内容ID的当前正则表达式:

public String getContentIdFromPathAndQueryString(String path, String queryString) {
        String contentId = null;
        if (StringUtils.isNonEmpty(path)) {
            Pattern p = Pattern.compile("([\\d]{9})(?=.html)");
            Matcher m = p.matcher(path);
            if (m.find()) {
                contentId = m.group();
            } else if (StringUtils.isNonEmpty(queryString)) {
                p = Pattern.compile("(?:contentId=)([\\d]{9})(?=.html)");
                m = p.matcher(queryString);
                if (m.find()) {
                    contentId = m.group();
                }
            }
        }

        Log.d(LOG_TAG, "Content id " + (contentId == null ? "not found" : (" found - " + contentId)));
        if (StringUtils.isEmpty(contentId)) {
            Answers.getInstance().logCustom(new CustomEvent("eid_url")
                    .putCustomAttribute("contentId", "empty")
                    .putCustomAttribute("path", path)
                    .putCustomAttribute("query", queryString));
        }

        return contentId;
    }
问题是: 这可以完成任务,但我需要解释一个特定的错误场景


无论是谁创建推送,都可能输入错误长度的内容ID,我们需要获取它,所以假设它可以是任意数量的数字。。。标题也可以包含数字,这很烦人。内容ID后面总是跟着“.html”

,而这里的基本答案是“替换
{9}
限制量词与
+
量词匹配1+个匹配次数”,有两种模式可以改进

应在模式中转义未转义的点,以匹配文字点

如果没有重叠匹配,则无需对前面的捕获组使用正向前瞻,只需保留捕获组并抓取
.group(1)
值即可

A仍然是一种消费模式,
(?:contentId=)
等于
contentId=
(您可以删除
(?:

无需将单个原子封装在一个原子中,请使用
\\d
而不是
[\\d]
[\\d]
实际上是一个误解的来源,有些人可能认为这是一个分组结构,可能会尝试将替代序列添加到方括号中,而
[…]
只匹配一个字符

因此,您的代码可以如下所示

        Pattern p = Pattern.compile("(\\d+)\\.html");     // No lookahead, + instead of {9}
        Matcher m = p.matcher(path);
        if (m.find()) {
            contentId = m.group(1);                       // (1) refers to Group 1
        } else if (StringUtils.isNonEmpty(queryString)) {
            p = Pattern.compile("contentId=(\\d+)\\.html");
            m = p.matcher(queryString);
            if (m.find()) {
                contentId = m.group(1);
            }
        }

{9}
替换为
+
(一次或多次出现)。这会绕过内容ID之前标题部分中的任何数字吗?请参阅伟大的工具!非常感谢。要确认,android中java的正则表达式应该是:Pattern p=Pattern.compile([\d]+)(?=.html)”;对吗?是的,如果您想使用
.group()
,整个匹配值,则不需要捕获组。如果您只需要第二个数字,请使用
contentId=(\\d+\\\\.html”
并使用
组访问数字(1)