2017-02-23 114 views
0

Это мой шаблон регулярного выражения:Как найти дополнительную группу с некоторым префиксом с помощью Regex

"subcategory.html?.*id=(.*?)&.*title=(.+)?" 

для ниже входного

http://example.com/xyz/subcategory.html?id=3000080292&backTitle=Back&title=BabySale Я хочу capturebelow группу

  • группы один (идентификатор): 3000080292
  • группа 2 (название): BabySale

Для этого он отлично работает. Проблема в том, что я хочу сделать вторую группу, т. Е. Значение заголовка, необязательным, так что даже если название отсутствует, регулярное выражение должно совпадать и получить значение группы 1 (id). Но для ввода

http://example.com/xyz/subcategory.html?id=3000080292&backTitle=Back& 

Повторное совпадение не срабатывает, даже если присутствует группа 1. Итак, мой вопрос заключается в том, как сделать вторую группу необязательной здесь?

+0

Прошу прощения, но если ваш прецедент извлекается для разбора URL-адресов, ma ybe вы должны увидеть http://stackoverflow.com/questions/13592236/parse-a-uri-string-into-name-value-collection или даже использовать одну из многих библиотек, выполняющих то же самое. Regex имеет тенденцию быть уязвимым при выполнении такого рода вещей. –

ответ

1

Возможно ли сделать всю подстроку опциональной?

Попробуйте subcategory.html?.*id=(.*?)&.*(?:title=(.+)?)?

отметить также, что ваш (и мое) регулярное выражение может быть соответствие слишком много. Например, точка здесь должна, вероятно, сбежать: subcategory\.html вместо subcategory.html или вы будете соответствовать subcategory€html, тоже. Ваш знак вопроса говорит, что lhtml не является обязательным; вероятно, вы сохраните файл .* («соответствовать чему-либо»), что следует.

Последнее, но не менее, окончательное .* означает, что даже это будет соответствовать (которые вы, вероятно, не хотите, чтобы соответствовать):

http://example.com/xyz/subcategory.html?id=3000080292&backTitle=Back&title=BabySale&Lorem Ipsum Sit Atem http://&%$ 

Это, как правило, плохая идея, чтобы соответствовать .*, как это будет почти всегда матч слишком много. Рассмотрите возможность использования классов символов вместо точки и привяжите его начало (^) и конец ($) строки ...:)

+0

, но выше regex не соответствует http://example.com/xyz/subcategory.html?id=3000080292&backTitle=Back& для первой группы –

+0

Когда я пытаюсь, он не может найти что-либо для группы 2 (название), скорее всего, потому что предыдущий '. *' слишком жадный, что делает его неживым, чтобы исправить проблему, хотя 'backTitle' имеет капитал' T', и мы только ищем строчный. Это может сделать: 'subcategory \ .html \?. * Id = (. *?) & (?:. *? Title = (\ w +)?)?' - при условии, что заголовок приходит последним, и вы не хотите ' backTitle' ... См. https://regex101.com/r/H9OKlb/3 – Christian

+0

Примечание: вы используете Java, поэтому обязательно избегайте шаблона регулярного выражения! – Christian

2

Одним из возможных способов использовать что-то вроде:

subcategory\.html\?.*id=(.*?)&(.*title=(.+)?)? 
(.*title=(.+)?)? is optional now. 

смотрите пример here.

Как было предложено @Christian, лучше сделать .*titleне захватывая группу, и это не будет частью результата.

subcategory\.html\?.*id=(.*?)&(?:.*title=(.+)?)? 
+0

Возможно, вы захотите сделать группу вокруг бита 'title' не захватывающим (' (? :) 'вместо'() '), чтобы избежать того, чтобы механизм regex сохранял результат в переменной (таким образом, изменяя номера индексов из существующих): 'subcategory \ .html \?. * id = (. *?) & (?:. * title = (. +)?)?' – Christian

+0

, но выше regex не соответствует «http: // example.com/xyz/subcategory.html?id=3000080292&backTitle=Back& "для первой группы? –

1

Если вы знаете, что параметр id идет перед дополнительным title, то вы можете использовать это регулярное выражение, чтобы захватить id и дополнительные title параметры:

subcategory\.html\?id=([^&]*)(?:.*&)?(?:title=([^&]*))? 

RegEx Demo

В Java использовать это регулярное выражение:

final String regex = "subcategory\\.html\\?id=([^&]*)(?:.*&)?(?:title=([^&]*))?"; 
Смежные вопросы