#asp.net #regex #backreference
#asp.net #регулярное выражение #обратная ссылка
Вопрос:
Мне нужно найти значения атрибутов в файле ASPX с использованием регулярных выражений.
Это означает, что вам не нужно беспокоиться об искаженном HTML или любых проблемах, связанных с HTML.
Мне нужно найти значение определенного атрибута (LocText). Я хочу получить то, что находится внутри кавычек. Любые теги ASPX, такие как <%=, <%#, <%$ и т.д. Внутри значения не имеют смысла для этого атрибута, поэтому рассматриваются как его часть.
Регулярное выражение, с которого я начал, выглядит следующим образом:
LocText="([^"] )"
Это отлично работает, первая группа, которая является текстом результата, получает все, кроме двойных кавычек, которые там не разрешены (вместо них должно использоваться «)
Но ASPX-файл допускает использование одинарных кавычек — тогда должно быть применено второе регулярное выражение.
LocText='([^'] )'
Я мог бы использовать эти два регулярных выражения, но я ищу способ соединить их.
LocText=("([^"] )"|'([^'] )')
Это также работает, но кажется не очень эффективным, поскольку создает ненужное количество групп. Я думаю, что это можно было бы как-то сделать, используя обратные ссылки, но я не могу заставить это работать.
LocText=(["']{1})([^1] )1
Я думал, что таким образом я сохраню одинарную / двойную кавычку в первой группе, а затем я скажу ей прочитать все, что НЕ является символом, найденным в первой группе. Это снова заключено в цитату из первой группы. Очевидно, я ошибаюсь, и это работает не так.
Есть ли какой-либо способ, как соединить первые два выражения вместе, создавая минимальное количество групп, причем одна группа является значением атрибута, который я хочу получить? Возможно ли использовать обратную ссылку для значения в одинарных / двойных кавычках, или я совершенно неправильно понял их значение?
Ответ №1:
Я бы сказал, что ваше решение с чередованием не так уж плохо, но вы могли бы использовать именованные захваты, чтобы результат всегда был найден в значении одной и той же группы:
Regex regexObj = new Regex(@"LocText=(?:""(?<attr>[^""] )""|'(?<attr>[^'] )')");
resultString = regexObj.Match(subjectString).Groups["attr"].Value;
Объяснение:
LocText= # Match LocText=
(?: # Either match
"(?<attr>[^"] )" # "...", capture in named group <attr>
| # or match
'(?<attr>[^'] )' # '...', also capture in named group <attr>
) # End of alternation
Другим вариантом было бы использовать предварительные утверждения ( [^1]
не работает, потому что вы не можете размещать обратные ссылки внутри символьного класса, но вы можете использовать их в поисковых системах):
Regex regexObj = new Regex(@"LocText=([""'])((?:(?!1).)*)1");
resultString = regexObj.Match(subjectString).Groups[2].Value;
Объяснение:
LocText= # Match LocText=
(["']) # Match and capture (group 1) " or '
( # Match and capture (group 2)...
(?: # Try to match...
(?!1) # (unless it's the quote character we matched before)
. # any character
)* # repeat any number of times
) # End of capturing group 2
1 # Match the previous quote character