如何处理XHTML中嵌套<>字符的替换问题?
解决嵌套自定义标记的转换问题
针对你遇到的嵌套<>标记无法用普通正则处理的问题,以下是几个可行的解决思路:
1. XSLT递归模板处理(推荐,适配现有流程)
正则本身不擅长处理嵌套结构,而XSLT的递归模板可以通过维护嵌套层级,精准识别最外层标记的边界。
你可以编写一个递归模板,遍历文本时跟踪<和>的层级计数,当层级回到0时,就找到了最外层标记的结束位置,再将其转换为TEI对应的元素(比如<add>,对应原始文档的添加内容)。
示例模板代码:
<xsl:template name="process-nested-adds"> <xsl:param name="text"/> <xsl:param name="level" select="0"/> <xsl:choose> <xsl:when test="contains($text, '&lt;') or contains($text, '&gt;')"> <xsl:variable name="lt-pos" select="string-length(substring-before($text, '&lt;')) + 1"/> <xsl:variable name="gt-pos" select="string-length(substring-before($text, '&gt;')) + 1"/> <xsl:choose> <!-- 优先处理<,层级+1 --> <xsl:when test="contains($text, '&lt;') and ($lt-pos < $gt-pos or not(contains($text, '&gt;')))"> <xsl:value-of select="substring-before($text, '&lt;')"/> <xsl:if test="$level = 0"> <add> <!-- TEI添加内容的元素 --> </xsl:if> <xsl:call-template name="process-nested-adds"> <xsl:with-param name="text" select="substring-after($text, '&lt;')"/> <xsl:with-param name="level" select="$level + 1"/> </xsl:call-template> </xsl:when> <!-- 处理>,层级-1,层级为1时闭合最外层元素 --> <xsl:when test="contains($text, '&gt;')"> <xsl:if test="$level = 1"> </add> </xsl:if> <xsl:call-template name="process-nested-adds"> <xsl:with-param name="text" select="substring-after($text, '&gt;')"/> <xsl:with-param name="level" select="$level - 1"/> </xsl:call-template> </xsl:when> </xsl:choose> </xsl:when> <xsl:otherwise> <xsl:value-of select="$text"/> </xsl:otherwise> </xsl:choose> </xsl:template>
使用时,直接调用这个模板处理包含嵌套标记的文本节点即可。
2. 用支持递归正则的工具预处理
如果不想在XSLT中编写复杂模板,可以用支持递归匹配的正则引擎(比如Python的regex库)先批量处理嵌套标记,再进入XSLT流程。
以Python为例,递归正则可以匹配任意嵌套深度的<>标记:
import regex def convert_nested_tags(xhtml_content): # 匹配嵌套的<...>,替换为TEI的<add>元素 return regex.sub(r'<((?:[^<>]|(?R))*)>', r'<add>\1</add>', xhtml_content)
如果需要区分特殊标记(比如示例中的<X>),可以调整正则模式单独处理。
3. 占位符预处理(备选方案)
通过临时替换内层标记的转义字符,避免外层正则误匹配:
- 先循环将内层的
<替换为__LT__,>替换为__GT__; - 用普通正则处理外层的
<...>,转换为TEI元素; - 最后将占位符替换回原始的转义字符,再处理内层标记。
这个方法需要多轮替换,容错性不如前两种,仅作为备选。
内容的提问来源于stack exchange,提问作者ScottD
相关产品推荐
相关产品推荐

