代码之家  ›  专栏  ›  技术社区  ›  Mark Biek

帮助使用与其他内容之前或之后匹配的regex

  •  4
  • Mark Biek  · 技术社区  · 17 年前

    我有一堆XML,其中的行如下所示

    <_char font_name="/ITC Stone Serif Std Bold" italic="true" />
    

    但有时看起来像这样

    <_char font_size="88175" italic="true" font_name="/ITC Stone Serif Std Bold" />
    

    这就是我要做的

    • 替换 斜体=“真” 具有 斜体=“假” 每行包含 ITC石材系列标准粗体 不管它是在 斜体字 部分。

    这可以用一个正则表达式来完成吗?

    我不是在寻找实时解决方案。我只是有大量的XML文件中有这个“错误”,我正在尝试进行全局搜索,并用powergrep替换,它需要一个regex。如果脚本是唯一的方法,那么就这样吧。

    5 回复  |  直到 17 年前
        1
  •  3
  •   VonC    17 年前

    简单使用“”运算符是否满足您的要求?

    name="/ITC Stone Sans Std Bold"[^>]italic="(true)"|italic="(true)"[^>]font_name="/ITC Stone Serif Std Bold"
    

    它应该检测到属性名在后面的任何行,属性名为italic,值为true。

        2
  •  1
  •   zigdon    17 年前

    一般来说,使用re进行XML解析不是一个好主意。但如果你真的想要,最简单的方法是用两行来完成:

    if (/ITC Stone Serif Std Bold/) {
       s/italic="true"/italic="false"/g;
    }
    
        3
  •  0
  •   Jonathan Leffler    17 年前

    在Perl中-未测试:

    while (<>)
    {
        s/italic="true"/italic="false"/ if m%font_name="/ITC Stone Sans Std Bold" italic="true"|italic="true" font_name="/ITC Stone Serif Std Bold"%;
        print;
    }
    

    思想非常简单-可能需要一个全局限定符,如果同一行的其他部分可以包含斜体选项,可能需要更复杂的替换。

    还有-一个想法-你应该利用这个机会使符号统一,所以总是把斜体放在字体名的前面(或后面)?

        4
  •  0
  •   Markus Jarderot    17 年前
    Pattern: /(<_char(?=(?:\s+\w+="[^"]*")*?\s+font_name="[^"]*?ITC Stone Serif Std Bold[^"]*")(?:\s+\w+="[^"]*")*?\s+italic=")true(?=")/
    Replacement: '$1false'
    
        5
  •  0
  •   Brad Gilbert    17 年前

    Perl 5.10

    使用Perl5.10的新特性。

    s(
     <_char \s* [^>]*? \K (?: (?&font) \s+ (?&italic) | (?&italic) \s+ (?&font) )
     (?(DEFINE)
      (?<font>font_name="/ITC[ ]Stone[ ]Serif[ ]Std[ ]Bold")
      (?<italic>italic="true")
     )
    ){
     $+{font} . 'italic="false"'
    }xge
    

    警告:未测试。