1

我有以下 Java 字符串,我需要将其与正则表达式进行比较,但这些字符串可以包含可能存在或不存在的可选值,我需要根据它们的可用性执行不同的操作:

字符串 1:带序列号

uri =  https://myid.com/123/1234567890128/456/1111

字符串 2:无序列号

uri = https://myid.com/123/1234567890128

正如我们所看到的,传入的字符串可以有,/456/1111也可以没有。如何编写单个正则表达式函数来检查它是否存在?我写了一个正则表达式,但它只有在/456/1111存在时才有效:

uri.matches("(http|https)://.*/123/[0-9]{13}.*)")

在查看此处的一些答案后,我尝试添加可选值,如下所示:

uri.matches("(http|https)://.*/123/[0-9]{13}+([/456/[0-9]{1,20}]?)")

但由于某种原因,它不起作用。有人可以帮助我如何验证uri中是否存在任何字符串/456/1111。我觉得我错过了一些小东西。

4

3 回答 3

1

利用

^https?:\/\/.*\/123\/[0-9]{1,13}(?:/456/[0-9]{1,20})?$

证明

解释

--------------------------------------------------------------------------------
  ^                        the beginning of the string
--------------------------------------------------------------------------------
  http                     'http'
--------------------------------------------------------------------------------
  s?                       's' (optional (matching the most amount
                           possible))
--------------------------------------------------------------------------------
  :                        ':'
--------------------------------------------------------------------------------
  \/                       '/'
--------------------------------------------------------------------------------
  \/                       '/'
--------------------------------------------------------------------------------
  .*                       any character except \n (0 or more times
                           (matching the most amount possible))
--------------------------------------------------------------------------------
  \/                       '/'
--------------------------------------------------------------------------------
  123                      '123'
--------------------------------------------------------------------------------
  \/                       '/'
--------------------------------------------------------------------------------
  [0-9]{1,13}              any character of: '0' to '9' (between 1
                           and 13 times (matching the most amount
                           possible))
--------------------------------------------------------------------------------
  (?:                      group, but do not capture (optional
                           (matching the most amount possible)):
--------------------------------------------------------------------------------
    /456/                    '/456/'
--------------------------------------------------------------------------------
    [0-9]{1,20}              any character of: '0' to '9' (between 1
                             and 20 times (matching the most amount
                             possible))
--------------------------------------------------------------------------------
  )?                       end of grouping
--------------------------------------------------------------------------------
  $                        before an optional \n, and the end of the
                           string
于 2021-02-05T21:39:31.150 回答
1

regex101.com在这方面是您的朋友。

在该站点上查看您的正则表达式时,您会看到一些错误,例如:

  • ]最后有一个孤独的,这似乎是
  • 最后你?最后的目标是错误的组,把它移出括号。

类似的东西https?://[^/]+/123/\d{13}(?:/456/\d{1,20})? 应该适合你。

regex101 的好处是,在右侧您可以看到有关您的 regex 的详细说明,并且它准确地突出显示了哪个字符在做什么。

于 2021-02-05T15:11:26.340 回答
1

您尝试的模式不起作用的原因是因为在模式的最后一部分中,您有([/456/[0-9]{1,20}]?)这意味着:

  • (捕获组
    • [/456/[0-9]{1,20}匹配 0-9 或数字 0-9 的 1-20 次重复/(因为 0-9 也匹配 456)
    • ]?匹配可选]
  • )关闭组

相反,您可以做的是使最后一个组作为一个整体是可选的,而不使用字符类使用https?使 s 可选。

^https?://.*/123/[0-9]{13}(?:/456/[0-9]{1,20})?$

正则表达式演示| Java 演示

当你使用matches()它应该匹配整个字符串,你可以省略锚点^$

String uri1 =  "https://myid.com/123/1234567890128/456/1111";
String uri2 = "https://myid.com/123/1234567890128";
String uri3 = "https://myid.com/123/1234567890128/456/111122222222222222222";
String pattern = "https?://.*/123/[0-9]{13}(?:/456/[0-9]{1,20})?";

System.out.println(uri1.matches(pattern));
System.out.println(uri2.matches(pattern));
System.out.println(uri3.matches(pattern));

输出

true
true
false
于 2021-02-05T22:44:09.797 回答