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

Я ищу регулярное выражение, которое может преобразовывать мои теги шрифта (только с атрибутами размера и цвета) в теги span с соответствующим встроенным CSS. Это будет сделано в VB.NET, если это вообще поможет.

Мне также нужно регулярное выражение, чтобы пойти другим путем.

Ниже приведен пример преобразования, которое я ищу:

<font size="10">some text</font>

Чтобы потом стать:

<span style="font-size:10px;">some text</span>

Таким образом, преобразование тега и добавление «px» в конце любого размера шрифта (мне не нужно изменять / преобразовывать размер шрифта, просто вставьте px в конце).

Регулярное выражение должно обрабатывать тег шрифта, который имеет только атрибут размера, только атрибут цвета или оба:

<font size="10">some text</font>

<font color="#000000">some text</font>

<font size="10" color="#000000">some text</font>

<font color="#000000" size="10">some text</font>

Мне также нужно другое регулярное выражение для обратного преобразования. Так, например:

<span style="font-size:10px;">some text</span>

станет:

<font size="10">some text</font>

Как и до преобразования тега, но на этот раз без удаления «px», мне не нужно беспокоиться об изменении размера шрифта.

Опять же, это также должно соответствовать стилю размера, стилю шрифта и комбинации того и другого:

<span style="font-size:10px;">some text</span>

<span style="color:#000000;">some text</span>

<span style="font-size:10px; color:#000000;">some text</span>

<span style="color:#000000; font-size:10px;">some text</span>

Я извлекаю базовый HTML и текст из тегов CDATA в файл XML, а затем отображаю их на веб-странице. Текст также появляется в редакторе форматированного текста, поэтому его можно редактировать / переводить, а затем сохранять обратно в новый файл XML. Затем XML будет прочитан флэш-файлом, поэтому необходимо использовать устаревший HTML.

Причина, по которой я хочу преобразовать этот код, в основном для целей отображения. Чтобы правильно отобразить размеры текста и чтобы он работал с моим редактором форматированного текста, их необходимо преобразовать в XHTML / встроенный CSS. Редактор форматированного текста также будет генерировать XHTML / встроенный CSS, который мне потребуется для преобразования «назад» в стандартный HTML, прежде чем он будет сохранен в файле XML.

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

Я знаю, что соблазн будет сказать мне несколько различных способов настроить мой код для выполнения того, что я хочу, но есть так много других перестановок, которые я даже не упомянул, которые вынудили меня идти по этому пути, так буквально все, что я хочу сделать, - это преобразовать строку, содержащую стандартный HTML, в XHTML / встроенный CSS, а затем то же самое, но наоборот.

Ответы [ 6 ]

2 голосов
/ 26 марта 2010

Поскольку некоторые люди уже предупредили вас, я перейду к решению регулярных выражений.

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

  1. Вы можете использовать LINQ (в противном случае это нужно будет обновить)
  2. Теги Font / Span будут в нижнем регистре (font и span не FONT или SpAn)
  3. Каждое значение атрибута стиля будет правильно отформатировано, оканчиваясь точкой с запятой ; аналогично вашим образцам

Чувствительность к регистру может быть обработана довольно просто через RegexOptions.IgnoreCase, хотя, в свою очередь, значения словаря должны быть сохранены как ToLower, чтобы сохранить все постоянным при последующем доступе к значениям. Третий пункт гарантирует, что разделение текста не станет бесполезным.

Ниже приведен пример программы, которая демонстрирует замены.

Sub Main
    Dim inputs As String() = { _
        "<font size=""10"">some text</font>", _
        "<font color=""#000000"">some text</font>", _
        "<font size=""10"" color=""#000000"">some text</font>", _
        "<font color=""#000000"" size=""10"">some text</font>", _
        "<font size=""10"">some text</font> other text <font color=""#000000"">some text</font>", _
        "<span style=""font-size:10px;"">some text</span>", _
        "<span style=""color:#000000;"">some text</span>", _
        "<span style=""font-size:10px; color:#000000;"">some text</span>", _
        "<span style=""color:#000000; font-size:10px;"">some text</span>", _
        "<span style=""color:#000000; font-size:10px;"">some text</span> other <font color=""#000000"" size=""10"">some text</font>" _
    }

    Dim pattern As String = "<(?<Tag>font|span)\b(?<Attributes>[^>]+)>(?<Content>.+?)</\k<Tag>>"
    Dim rx As New Regex(pattern)

    For Each input As String In inputs
        Dim result As String = rx.Replace(input, AddressOf TransformTags)
        Console.WriteLine("Before: " & input)
        Console.WriteLine("After: " & result)
        Console.WriteLine()
    Next
End Sub

Public Function TransformTags(ByVal m As Match) As String
    Dim rx As New Regex("(?<Key>\b[a-zA-Z]+)=""(?<Value>.+?)""")
    Dim attributes = rx.Matches(m.Groups("Attributes").Value).Cast(Of Match)() _
                       .ToDictionary(Function(attribute) attribute.Groups("Key").Value, _
                                     Function(attribute) attribute.Groups("Value").Value)

    If m.Groups("Tag").Value = "font" Then
        Dim newAttributes = String.Join("; ", attributes.Select(Function(item) _
                                                If(item.Key = "size", "font-size", item.Key) _
                                                & ":" _
                                                & If(item.Key = "size", item.Value & "px", item.Value)) _
                                            .ToArray()) _
                                            & ";"
        Return "<span style=""" & newAttributes & """>" & m.Groups("Content").Value & "</span>"
    Else
        Dim newAttributes = String.Join(" ", attributes("style") _
                                             .Split(New Char() {";"c}, StringSplitOptions.RemoveEmptyEntries) _
                                             .Select(Function(s) _
                                                s.Trim().Replace("px", "").Replace("font-", "").Replace(":", "=""") _
                                                & """") _
                                        .ToArray())
        Return "<font " & newAttributes & ">"  & m.Groups("Content").Value & "</font>"
    End If
End Function

Если у вас есть какие-либо вопросы, дайте мне знать. Некоторые улучшения могут быть сделаны, если ожидается обработка большого количества текста. Например, объект regex в методе TransformTags можно переместить на уровень класса, чтобы он не создавался заново при каждом преобразовании.

РЕДАКТИРОВАТЬ: Вот объяснение первого шаблона: <(?<Tag>font|span)\b(?<Attributes>[^>]+)>(?<Content>.+?)</\k<Tag>>

  • <(?<Tag>font|span)\b - открытие < и сопоставление тега font или span и использование именованной группы Tag. \b соответствует границе слова, чтобы гарантировать, что ничего кроме указанных имен тегов не найдено.
  • (?<Attributes>[^>]+)> - именованная группа, Attributes, соответствует всему остальному в теге, если она не является символом >, тогда она соответствует закрывающему >
  • (?<Content>.+?) - именованная группа, Content, соответствует чему-либо между тегом
  • </\k<Tag>> - соответствует закрывающему тегу путем обратной ссылки на группу Tag

Второй шаблон используется для сопоставления пар ключ-значение для атрибутов: (?<Key>\b[a-zA-Z]+)=""(?<Value>.+?)""

  • (?<Key>\b[a-zA-Z]+) - именованная группа, Key, соответствует любому слову (алфавиту), начинающемуся с границы слова
  • ="" - соответствует символу равенства и открывающей цитате
  • (?<Value>.+?) - именованная группа, Value, соответствует чему-либо до закрывающей кавычки. Он не жадный, указав символ ? после символа +. Это могло бы быть [^""]+ похоже на то, как группа Attributes была обработана в первом шаблоне.
  • "" - соответствует закрывающей цитате
1 голос
/ 26 марта 2011

Я нашел решение этой проблемы. Однако это не тот, который предполагает использование регулярного выражения. Хотя мне очень интересна идея создания пользовательской программы и инструмента для создания графического интерфейса для достижения этой цели. Ссылка ниже предоставит самое простое решение для преобразования любых устаревших тегов шрифтов в встроенные теги span. Это важный и потрясающий инструмент.

http://tinymce.moxiecode.com/tryit/full.php

Нажатие на html покажет html-код сообщения. Затем вы можете заменить его HTML-кодом с устаревшими тегами , и они будут преобразованы в встроенные теги .

1 голос
/ 26 марта 2010

Не пытайтесь анализировать HTML с помощью регулярного выражения . Вместо этого используйте синтаксический анализ XML.

1 голос
/ 26 марта 2010

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

Придерживайтесь технологий на основе XML, таких как XSLT, для преобразования.

0 голосов
/ 26 марта 2010

Я согласен с обоими комментариями, говоря, что xslt должен использоваться для преобразования xml, и этот стиль не должен смешиваться в html ... но вот отправная точка для вашего регулярного выражения (perl, я не знаю никакого VB, но это не должно быть слишком далеко), если вы спешите:

's/<font(.*)size="([^ ]*)"(.*)color="([^ ]*)"(.*)<\/font>/<span$1style="font-size:$2px;color:$4"$3$5<\/span>/g'

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

0 голосов
/ 26 марта 2010

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

Может быть лучше потратить время на преобразование в отдельный код HTML и CSS на основе атрибутов class и id?

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