【问题标题】:Regex: Handle an Optional url part with delimiter正则表达式:处理带有分隔符的可选 url 部分
【发布时间】:2020-09-16 07:25:30
【问题描述】:

我正在尝试匹配一些这样构建的网址:

https://tenantName-dev.somedomain.com/somefile.js
https://tenantName-qa.somedomain.com/somefile.js
https://tenantName.somedomain.com/somefile.js

注意最后一个没有“环境”的,因为它是产品。

到目前为止我的 C# 正则表达式:

https://(?<tenantName>.+)-(?<environment>[^.]*).(?<rootDomain>[^/]+)/somefile.js

这通常有效,但与最后一个不匹配,因为它总是需要一个“-”。 如果我只是让那个破折号成为可选的,那么它会匹配像 'https://tenant-.somedomain...' 这样不好的东西。

我尝试查看前瞻组和非捕获组来表达这样一个事实,即只有在后面有租户但没有成功时我才想要一个“-”。

【问题讨论】:

  • https:\/\/(?&lt;tenantName&gt;.+)(-(?&lt;environment&gt;[^.]*))?\.(?&lt;rootDomain&gt;[^\/]+)\/somefile.js 怎么样? regex101.com/r/VmDlFf/1
  • 试试https://(?&lt;tenantName&gt;\w+)[-.](?&lt;environment&gt;[^/]*)\.(?&lt;rootDomain&gt;[^/.]+)/somefile\.js
  • 太贪心了,所以你依赖于前面的- 和最后的.js 的位置结构,但对于只有1 个点的域不要acnt,但是是吗?你靠贪心排队灯芯是不行的。到目前为止,所有的 sugestunz 都不好
  • user 和 @wiktor-stribiżew 您的两个建议都允许我匹配以下字符串,这是不可接受的 tenantName-.somedomain.com/somefile.js

标签: .net regex regex-group


【解决方案1】:

在大多数正则表达式(和 .Net 的版本)中,有一个 条件 模式允许检查,例如if...then...else。这是由(?({conditon})X|Y) 完成的,如果匹配条件为真X 完成,否则 Y 完成)。

通过这样做来测试它(注意打开标志IgnorePatternWhitespace,因为我正在评论正则表达式):

 (?(?:.+-)   # If a dash
  (?<A>.+)   # Match for dash
 |           # Else Then   
  (?<B>.+)   # Match this
)

所以条件是前瞻,即?:.+-,这意味着前方某处有-。如果真匹配并创建一个命名的捕获组A。否则在组 B 上创建一个匹配项。


因此,我们可以提取您的模式并将其集中在 - 上。比如

https://
(?(?:.+-)    # If a dash
  (
    (?<tenantName>[^-]+)-(?<environment>[^.]+)
  )
 |           # Else Then   
  (
    (?<tenantName>[^.]+)
  ) 
)
\.(?<rootDomain>[^/]+)

因此,如果我们在有 - 时转储匹配项,匹配项中的组配置文件如下所示:

Match #0
                    [0]:  https://tenantName-dev.somedomain.com
            ["1"] → [1]:  
            ["2"] → [2]:  
   ["tenantName"] → [3]:  tenantName
            →3 Captures:  tenantName
  ["environment"] → [4]:  dev
            →4 Captures:  dev
   ["rootDomain"] → [5]:  somedomain.com
            →5 Captures:  somedomain.com

请注意,上面的索引对[3] 有效,或者更好地使用["tenantName"] 的命名捕获,它给我们“tenantName”和["environment"],它给我们“dev”。

取出-dev,匹配转储如下所示:

Match #0
                    [0]:  https://tenantName.somedomain.com
            ["1"] → [1]:  tenantName
            →1 Captures:  tenantName
            ["2"] → [2]:  
   ["tenantName"] → [3]:  tenantName
            →3 Captures:  tenantName
  ["environment"] → [4]:  
   ["rootDomain"] → [5]:  somedomain.com
            →5 Captures:  somedomain.com

对于那个["environment"] 组没有代表,我们可以检查Successmtch.Groups["Dev"].Success。示例:

var pattern = @"https://
(?(?:.+-)    # If a dash
  (
    (?<tenantName>[^-]+)-(?<environment>[^.]+)
  )
 |           # Else Then
  (
    (?<tenantName>[^.]+)
  )
)
\.(?<rootDomain>[^/]+)";

var url = "https://tenantName.somedomain.com/somefile.js";

var mtch = Regex.Match(url, pattern, RegexOptions.IgnorePatternWhitespace);

if (mtch.Groups["Dev"].Success)
   ...

【讨论】:

    猜你喜欢
    • 2012-05-10
    • 2011-07-26
    • 1970-01-01
    • 2014-06-06
    • 2020-04-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多