Анализ регулярных выражений атрибута ASPX в c#

#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