【问题标题】:How to ignore some delimited text when doing Python re.sub执行 Python re.sub 时如何忽略一些分隔文本
【发布时间】:2020-09-27 18:14:23
【问题描述】:

我正在尝试“解析”一些 LaTeX 代码。 LaTeX 使用了一些特殊字符,例如%#{},并用$ … $ 分隔内联数学环境。

我需要的是转义 (\) 所有尚未转义且 不在 内的特殊字符 $ … $

例如,对于提供的条目

#s{o}me\%thing $ \text{a} $

我需要返回:

\#s\{o\}me\%thing $ \text{a} $

请注意,已经转义的 \% 以及 $ … $ 中的 \text{a} 保持不变。

我正在使用 Python 的 re.sub 来做到这一点,这样我可以忽略转义的,但我不知道如何忽略 $ … $ 环境。我当前的代码是:

string = "#s{o}me\%thing $ \text{a} $"
re.sub(r'([^\\]?)((?:%|#|{|}|&))', r"\1\\\2", string)
# Expected output: "\#s\{o\}me\%thing $ \text{a} $"
# Actual output:   "\#s\{o\}me\%thing $ \text\{a\} $"

此时,对于上面的示例,我的代码返回以下内容:

\#s\{o\}me\%thing $ \text\{a\} $

有什么建议吗??

【问题讨论】:

    标签: python regex string replace


    【解决方案1】:

    您可以考虑以下解决方案:

    import re
    s = r"#s{o}me\%thing $ \text{a} $"
    rx = r'(?<!\\)((?:\\{2})*)(?:(\$[^$\\]*(?:\\.[^$\\]*)*\$)|([%#{}&]))'
    print ( re.sub(rx, lambda x: fr"{x.group(1)}\{x.group(3)}" if x.group(3) else fr"{x.group(1)}{x.group(2)}", s, flags=re.S) )
    # => \#s\{o\}me\%thing $ \text{a} $
    

    查看Python demo

    正则表达式是

    (?<!\\)((?:\\{2})*)(?:(\$[^$\\]*(?:\\.[^$\\]*)*\$)|([%#{}&]))
    

    请参阅regex demo。详情:

    • (?&lt;!\\) - 不允许 \ 紧邻当前位置的左侧
    • ((?:\\{2})*) - 第 1 组:零个或多个双反斜杠序列
    • (?:(\$[^$\\]*(?:\\.[^$\\]*)*\$)|([%#{}&amp;])) - 任何一个
      • (\$[^$\\]*(?:\\.[^$\\]*)*\$) - 第 2 组:$,然后是除 \$ 之外的任何零个或多个字符,然后出现零个或多个转义序列(\ + 任何字符),然后是任何零个或多个字符\$ 以外的字符,然后是 $
      • | - 或
      • ([%#{}&amp;]) - 第 3 组:%#{}&amp;

    如果第 3 组匹配,则将匹配替换为第 1 组 + \ + 第 3 组值,否则,结果是第 1 组和第 2 组值的串联。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-03-17
      • 2011-09-06
      • 1970-01-01
      • 2018-03-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多