Соответствие регулярного выражения частям URL - PullRequest
2 голосов
/ 29 мая 2011

Мне нужно сопоставить эти части следующей строки:

(user)@(hostname):(port)

Пользователь и порт могут быть сопоставлены.Сначала я справился с этим регулярным выражением:

(?:([^@]*)@)?([^\:]+)(?:\:(\d+))?

Это соответствует foo@bar:80

foo
bar
80

Но когда речь идет о хосте IPv6, таком как foo@[2001:0db8:85a3:08d3:1319:8a2e:0370:7344]:80, вышло предыдущее регулярное выражениеработает не так, как ожидалось:

foo
[2001
0

Так что теперь я размышляю над регулярным выражением, которое также может сопоставлять узлы, заключенные в квадратные скобки, с двоеточиями, но без квадратных скобок.:) Я сделал это с помощью следующего регулярного выражения:

(?:([^@]*)@)(?:\[(.+)\]|([^:]+))(?:\:(\d+))?

foo
2001:0db8:85a3:08d3:1319:8a2e:0370:7344
<empty>
80

Но ... это ужасно, потому что либо 2, либо 3 будет пустым.Есть ли способ объединить это только с одной обратной ссылкой?

Я использую boost :: regex, который, насколько я знаю, использует движок регулярных выражений perl.

Спасибо и с уважением

reeaal

1 Ответ

2 голосов
/ 29 мая 2011
(?:([^@]*)@)(\[.+\]|([^:]+))(?:\:(\d+))?

Но вам придется удалить [], если это IPv6-адрес. Хотя должно быть довольно тривиальным.

Вы также можете сделать это с необязательными [ и ] до и после, а затем посмотреть на некоторые утверждения ... но это действительно ужасно; ваши коллеги-программисты будут вам благодарны, если вы просто поцелуетесь и будете использовать все вышеперечисленное, но вот вариант:

(?:([^@]*)@)\[?((?<=\[).+(?=\])|([^:]+))\]?(?:\:(\d+))?
...