从字体到跨度(大小和颜色)和背面(VB.NET)的正则表达式

时间:2010-03-26 13:07:28

标签: html css vb.net regex

我正在寻找一个正则表达式,可以将我的字体标记(仅限大小和颜色属性)转换为带有相关内联css的span标记。这将在VB.NET中完成,如果这有用的话。

我还需要一个正则表达式来反过来。

下面详细说明我正在寻找的转换示例:

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

然后成为:

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

所以转换标签并在任何字体大小的末尾添加“px”(我不需要更改/转换字体大小,只需在末尾粘贴px)。

正则表达式需要处理只有size属性,只有color属性或两者的字体标记:

<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&amp;来自XML文件中的CDATA标记的文本,然后在网页上显示它们。该文本也出现在富文本编辑器中,因此可以对其进行编辑/翻译,然后将其保存回新的XML文件中。然后,XML将被flash文件读取,因此需要使用老式的HTML。

我想转换此代码的原因主要是用于显示目的。为了正确显示文本大小并使其与我的富文本编辑器一起使用,需要将它们转换为XHTML /内联CSS。富文本编辑器还将生成XHTML /内联CSS,在将其保存到XML文件中之前,我需要将其“返回”转换为标准HTML。

我不太了解XSLT转换,但我不确定这是我需要的,或者它可能比我现在需要的更多,但是如果我错了请纠正我(并指出我指的是你可能有的任何有用的链接。)

我知道诱惑将是告诉我一些不同的方法来设置我的代码来做我想要的但是还有很多其他的排列我甚至没有提到过哪些强迫我沿着这条路走下去,所以字面意思我想要做的就是将包含标准HTML的字符串转换为XHTML / inline CSS,然后将其转换为相同但反过来。

6 个答案:

答案 0 :(得分:2)

由于有些人已经给你警告,我将跳到正则表达式解决方案。

首先,我将列出几个不尽相同的假设但允许在你没有做额外工作的情况下解决问题:

  1. 您可以使用LINQ(否则需要更新)
  2. 字体/跨度代码将采用小写字母(fontspan而非FONTSpAn
  3. 每个样式属性值都将正确格式化,以与您的样本类似的分号;结尾
  4. 区分大小写只需通过RegexOptions.IgnoreCase即可,但反过来,字典值需要存储为ToLower,以便在以后访问值时保持所有内容不变。第3点确保拆分文本不会出错。

    以下是演示替换的示例程序。

    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
    

    如果您有任何疑问,请告诉我。如果预计会处理大量文本,则可以进行一些增强。例如,TransformTags方法中的regex对象可以移动到类级别,因此不会在每次转换时重新创建它。

    编辑:以下是第一种模式的解释:<(?<Tag>font|span)\b(?<Attributes>[^>]+)>(?<Content>.+?)</\k<Tag>>

    • <(?<Tag>font|span)\b - 打开<并匹配字体或范围标记,并使用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 :(得分:1)

我不认为正则表达式是解决这个问题的方法。

坚持使用基于XML的技术,例如XSLT进行转换。

答案 2 :(得分:1)

You shouldn't try to parse HTML with regex。改为使用XML解析。

答案 3 :(得分:1)

我找到了解决这个问题的方法。然而,它不涉及使用正则表达式。虽然我对创建自定义程序和GUI创建工具的想法非常感兴趣,但实现这一目标。下面的链接将提供最简单的解决方案,将任何已弃用的字体标记转换为内联span标记。这是一个至关重要且令人敬畏的工具。

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

点击html将显示该消息的html代码。然后你可以用已弃用的&lt; font&gt;的html替换它。标签,它们将转换为内联&lt; span&gt;标签

答案 4 :(得分:0)

解释你为什么需要这样做可能是一个好主意,因为除非有一个特定的目标,否则这似乎将一种非语义代码转换为另一种非语义代码。

根据classid属性,是否可以花时间转换为单独的HTML和CSS代码?

答案 5 :(得分:0)

我同意这两条评论说xslt应该用于xml转换,并且该样式不应该在html中混合......但这里是你的正则表达式的起点(perl,我不知道任何VB但是它如果你赶时间,那就不应该太远了:

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

我不认为你可以在一个正则表达式中执行此操作,这个处理大小在颜色之前的情况,你可以从这里得到3个缺少的正则表达式...