Регулярное выражение для преобразования ul в textformat и обратно, с другим значением атрибута для первого тега (VB.NET) - PullRequest
0 голосов
/ 01 апреля 2010

Это связано с предыдущим вопросом, который я задал здесь, см. Ссылку ниже для краткого описания того, почему я пытаюсь это сделать.

Регулярное выражение от шрифта до диапазона (размер и цвет) и обратно (VB.NET)

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

Например:

<ul>
   <li>This is some text</li>
   <li>This is some more text</li>
   <li>
      <ul>
         <li>This is some indented text</li>
         <li>This is some more text</li>
      </ul>
   </li>
   <li>More text!</li>
   <li>
      <ul>
         <li>This is some indented text</li>
         <li>This is some more text</li>
      </ul>
   </li>
   <li>More text!</li>
</ul>

<ul>
   <li>Another list item</li>
   <li>
      <ul>
         <li>Another nested list item</li>
       </ul>
   </li>
</ul>

станет:

<textformat indent="0">
   <li>This is some text</li>
   <li>This is some more text</li>
   <li>
      <textformat indent="20">
         <li>This is some indented text</li>
         <li>This is some more text</li>
      </textformat>
   </li>
   <li>More text!</li>
   <li>
      <textformat indent="20">
         <li>This is some indented text</li>
         <li>This is some more text</li>
      </textformat>
   </li>
   <li>More text!</li>
</textformat>

<textformat indent="0">
   <li>Another list item</li>
   <li>
      <textformat indent="20">
         <li>Another nested list item</li>
      </textformat>
   </li>
</textformat>

По сути, я хочу, чтобы первый тег ul не имел отступа, но все вложенные теги ul должны иметь отступ 20.

Я ценю, что это странная просьба, но, надеюсь, она имеет смысл, пожалуйста, дайте мне знать, если у вас есть какие-либо вопросы.

Заранее спасибо.

Ответы [ 2 ]

1 голос
/ 01 апреля 2010

Это возможно с регулярным выражением, но LINQ to XML проще. Я включил LINQ to XML и решение для регулярных выражений, хотя я бы предпочел первое.

Вот подход LINQ to XML. Поскольку ul является верхним элементом, его Name можно изменить напрямую. Descendants захватит все вложенные ul предметы. Единственное предостережение при таком подходе - он работает только в том случае, если входные данные правильно сформированы. Если это неправильно, LINQ to XML не сможет его проанализировать. Кроме того, если он правильно сформирован и ul не является верхним элементом, но является частью более крупного блока HTML-текста, тогда вам нужно перебрать Elements("ul"), а затем проделать то же самое с каждым из них.

Если HTML-код искажен, вы можете обратиться к HTML Agility Pack .

Dim xml = XElement.Parse(input)
xml.Name = "textformat"
xml.SetAttributeValue("indent", "0")
For Each item In xml.Descendants("ul")
    item.Name = "textformat"
    item.SetAttributeValue("indent", "20")
Next

А вот и подход к регулярным выражениям. Нелегко обнаружить первый элемент ul, чтобы различать два, поэтому этот подход меняет их все на отступ 20, затем делается дополнительный шаг, чтобы найти первый textformat и изменить его отступ на ноль.

Dim pattern As String = "<ul>|</ul>"
Dim result As String = Regex.Replace(input, pattern, Function(m) If(m.Value.StartsWith("</"), "</textformat>", "<textformat indent=""20"">"))
Dim firstTextFormatPattern As String = "^(?<Start><textformat\s+indent="")\d+?(?<End>"">)"
result = Regex.Replace(result, firstTextFormatPattern, "${Start}0${End}")
0 голосов
/ 07 апреля 2010

Спасибо за вашу помощь, мне удалось самостоятельно найти решение, используя ваш ответ.

Обычно я использую счетчик, чтобы отслеживать, какой уровень тега ul нашел регулярное выражение, а затем заменяю его соответствующим атрибутом:

Dim ulCounter As Integer = 0    
Dim rxUL As New Regex("<ul>|</ul>")

xmlValue = rxUL.Replace(xmlValue, AddressOf Convert_UL)


Protected Function Convert_UL(ByVal m As Match) As String

    Dim HTML As String = ""

    If m.Value = "</ul>" Then
        ulCounter -= 1

        HTML = "</textformat>"
    Else
        ulCounter += 1

        If ulCounter > 1 Then
            HTML = "<textformat indent=""20"">"
        Else
            HTML = "<textformat indent=""0"">"
        End If
    End If

    Return HTML

End Function

Это был довольно случайный запрос, поэтому я не уверен, насколько это может помочь кому-либо еще, но на всякий случай, как я его обошел!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...