Регулярное выражение замены HTML-тега работает не совсем корректно - PullRequest
0 голосов
/ 14 сентября 2009

Это продолжение до другого вопроса моего. Решение, которое я нашел, прекрасно работало для каждого из тестовых случаев, которые я ему бросил, пока не обнаружился случай, который ускользнул от меня в первый раз.

Моя цель - переформатировать неправильно отформатированные атрибуты тегов с помощью регулярных выражений (я знаю, что, как я выяснил, возможно, это не надежный метод, но терпите меня).

Мои функции:

Public Function ConvertMarkupAttributeQuoteType(ByVal html As String) As String
    Dim findTags As String = "</?\w+((\s+\w+(\s*=\s*(?:"".*?""|'.*?'|[^'"">\s]+))?)+\s*|\s*)/?>"
    Return Regex.Replace(html, findTags, AddressOf EvaluateTag)
End Function

Private Function EvaluateTag(ByVal match As Match) As String
    Dim attributes As String = "\s*=\s*(?:(['""])(?<g1>(?:(?!\1).)*)\1|(?<g1>\S+))"
    Return Regex.Replace(match.Value, attributes, "='$2'")
End Function

Регулярное выражение в функции EvaluateTag будет правильно преобразовывать HTML как

<table border=2 cellpadding='2' cellspacing="1">

в

<table border='2' cellpadding='2' cellspacing='1'>

Вы заметите, что я заставляю значения атрибута заключать в одинарные кавычки - не беспокойтесь об этом. Случай, в который он входит, - это если значение атрибута last не имеет ничего вокруг.

<table width=100 border=0>

выходит из регулярного выражения и заменяется на

<table width='100' border='0>'

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

Спасибо!

Ответы [ 2 ]

1 голос
/ 15 сентября 2009

объяснение Ричардталента о том, почему регулярное выражение не работало, указало мне правильное направление. Немного поиграв, похоже, работает следующая замена функции EvaluateTag.

Кто-нибудь может увидеть что-нибудь проблемное с этим? Изменения, которые я сделал, находятся в последней группе после канала. Может быть, это еще больше упростит?

 Private Function EvaluateTag(ByVal match As Match) As String
   Dim attributes As String = "\s*=\s*(?:(['""])(?<g1>(?:(?!\1).)*)\1|(?<g1>[^>\s]+))"
   Return Regex.Replace(match.Value, attributes, "='$2'")
 End Function

Если никто не ответит, я, вероятно, приму это как ответ. Еще раз спасибо!

1 голос
/ 14 сентября 2009

Первая функция RegEx передаст EvaluateTag совпадение whole , представляющее собой весь тег HTML.

Но EvaluateTag не игнорирует последний символ больше ...

Боюсь, у меня еще не было достаточного количества кофеина для проработки всего выражения, но эта корректировка может работать (добавлено больше, чем в списке символов):

 Private Function EvaluateTag(ByVal match As Match) As String
   Dim attributes As String = "\s*=\s*(?:(['"">])(?<g1>(?:(?!\1).)*)\1|(?<g1>\S+))"
   Return Regex.Replace(match.Value, attributes, "='$2'")
 End Function
...