Regex: обрабатывать необязательную часть URL-адреса с разделителем - PullRequest
1 голос
/ 28 мая 2020

Я пытаюсь сопоставить некоторые URL-адреса, которые построены следующим образом:

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

Обратите внимание на последний, у которого нет «среды», так как он является продуктом. regex на данный момент:

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

Это в основном работает, но не соответствует последнему, поскольку всегда ожидает '-'. Если я просто сделаю это da sh optinal, тогда он будет соответствовать примерно 'https://tenant-.somedomain ...', что не очень хорошо.

Я пробовал смотреть вперед и не захватывать группирует на express тот факт, что я хочу '-' только в том случае, если есть арендатор, но не добился успеха.

1 Ответ

0 голосов
/ 29 мая 2020

В большинстве разновидностей регулярных выражений ( и в. Net версии ) есть шаблон условный , который позволяет выполнять проверку, например if...then...else. Это выполняется с помощью (?({conditon})X|Y), где, если условие совпадения истинно, выполняется X, а если нет , то выполняется Y).

Проверьте это, выполнив это ( обратите внимание, включите флаг IgnorePatternWhitespace, потому что я комментирую регулярное выражение ):

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

Таким образом, условие является предварительным что означает ?:.+-, что означает, что где-то впереди есть -. Если true, сопоставьте и создайте именованную группу захвата 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"] не отображается, и мы можем проверить Success как mtch.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)
   ...
...