Во-первых, ^
в вашем регулярном выражении означает «начало строки», то есть вы хотите только совместить дату в начале строки (что неверно для вас). Так что удалите его. То же самое с «$», что означает «конец строки».
Во-вторых, [0|1]
означает «совпадающие символы 0, 1 или 1». Вероятно, вы хотите, чтобы [01]
означало «совпадающие символы 0 или 1».
В-третьих, у вас есть дополнительный закрывающий кронштейн с непревзойденным открывающим кронштейном в ваших регулярных выражениях.
В-четвертых, как общая точка стиля, [0]
- это то же самое, что и 0
, поэтому квадратные скобки здесь избыточны.
Так что ваши (! Не совсем) «фиксированный» регулярное выражение:
(?:(?:\s*/)(?<StartDate>(0?[1-9]|[12][0-9]|[3][01])[. -](0?[1-9]|1[0-2])[. -]([0-9]{4}|[0-9]{2})))*
(?:(?:\s*/)(?<EndDate>(0?[1-9]|[12][0-9]|3[01])[. -](0?[1-9]|1[0-2])[. -]([0-9]{4}|[0-9]{2})))*
Однако это не соответствовать вашей тестовой строки из-за дополнительного «/ testModule» в строке, которая не находится в ваше рабочее регулярное выражение где угодно. Вы можете изменить исходное регулярное выражение, чтобы разрешить дополнительные косые черты между двумя частями регулярного выражения?
<original regex>
(?:/[^/]+)* # <-- for the /testModule and any other similar tokens that appear in between
<date regex>
Также в качестве общей точки
- у вас есть несколько вхождений
(?:(?:regex)*)*
. Я не уверен, что суть удвоения внешнего *
, кроме того, что синтаксический анализатор регулярных выражений работает намного труднее, чем нужно, без всякой причины (внешний (?:)*
здесь избыточен).
- нет смысла делать
(?:/\s*)
, как вы ничего с кронштейнами не делать, так что просто сделать /\s*
- же с такими вещами как
(?:/client:)
. Почему бы не захватывать скобки, если вы ничего не делаете с ними. /client:
сделаю.
(?:regex)*
означает «соответствует 0 на бесконечность вхождениях regex
». С такими вещами, как (?:\s*/(?<ClientHelp>help))*
, вы действительно ожидаете, что это произойдет бесконечно много раз в вашей строке, или оно появится только один раз или совсем?Рассмотрим замену *
на ?
, что означает «совпадение 0 или 1 вхождения» (если вы знаете, что этот токен появится один или несколько раз) или замените его (скажем) {0, 100}
, если вы знаете, что этот токен появится на 100 раз (и не менее 0 раз). Это может повысить производительность.
Так что рекомендую изменить регулярное выражение, как это:
(?<GeneralHelp>^/help\s*)?
/client:
(?<Client>\w*)
(?:\s*/(?<ClientHelp>help))*
(?:\s*/(?<Modules>createHistory)(?:\s*/(?<ModuleHelp>help))*)*
(?:/[^/]+)*
(?:\s*/(?<StartDate>(0?[1-9]|[12][0-9]|[3][01])[. -](0?[1-9]|1[0-2])[. -]([0-9]{4}|[0-9]{2})))*
(?:\s*/(?<EndDate>(0?[1-9]|[12][0-9]|3[01])[. -](0?[1-9]|1[0-2])[. -]([0-9]{4}|[0-9]{2})))*
Вы можете возиться с регулярным выражением в regexr, где я создал пример с регулярным выражением/тестовой строкой. (Изменить: < и> в регулярном выражении, кажется, были изменены на < и > в RegExr поэтому ссылка не будет работать, если не копировать/вставить регулярное выражение я написал прямо)
Вы должны добавить некоторые примеры данных, к которым применяется регулярное выражение. Также преднамеренно, что вы не избежали '.' и' -' внутри '[. -] '? Насколько я знаю, они все равно должны интерпретироваться, поэтому '.' Будет соответствовать любому символу, а не только периодам. – Mario
@Mario: na, [. -] означает «матч., пробел или -». поскольку «-» является последним в классе символов, нет проблем с сопоставлением непреднамеренных диапазонов. –
@Mario: внутри квадратных скобок, '.' - это просто точка и' -' просто дефис, если он находится рядом с скобкой. @Kendra: есть ли причина, по которой вы используете неселективные скобки на '(?: \ S * /)'? – Robin