【问题标题】:Excluding a single pattern from a perl search and replace with word boundary matching从 perl 搜索中排除单个模式并用单词边界匹配替换
【发布时间】:2012-02-18 11:59:48
【问题描述】:

this perl newbie question后,我有一个perl新手跟进。我发现了一种情况,在我的应用程序中使用单词边界失败,该应用程序执行此正则表达式搜索并替换一组文件:

s/\bcat\b/cat_tastic/g

我也希望 -cat 不匹配替换,尽管它目前是匹配的,因为连字符被认为是单词边界。我已经阅读了单词边界,但我了解到的是,在使用 \b 时创建对边界条件的更改并非易事。如何从搜索和替换中排除“-cat”?所以最终的结果是:

:cat { --> :cat_tastic {
:catalog { --> no change
-cat { --> no change

这不一定是单行搜索和替换的一部分,它也可以是搜索和替换之前的一个条件,它控制是否执行搜索和替换,尽管将它放在搜索和替换中会最有用。

【问题讨论】:

    标签: regex perl


    【解决方案1】:

    这不是一个新手正则表达式,但它似乎最适合您的模式:使用“消极的lookbehind”表达式,表示“我希望我匹配的内容不跟随连字符:

    s/(?<!-)\bcat\b/cat_tastic/g
    

    附录:这可以完成这项工作,但更通用的方法(也可移植到具有较少花哨的正则表达式的语言)是将此类问题分为两个:不是连字符后的 cat,或字符串开头的 cat:

    s/([^-])\bcat\b|^\bcat\b/\1cat_tastic/g
    

    或者更好:

    s/([^-]|^)\bcat\b/\1cat_tastic/g
    

    【讨论】:

      【解决方案2】:

      如果您的案例中的“单词边界”根据您的评论与“a-z、A-Z、0123456789 以及下划线和连字符”一起出现,您可以使用字符类:

      s/(?<![\w-])cat(?![\w-])/cat_tastic/g
      

      字边界\b 出现在匹配\w 的字符不与另一个\w 字符接壤的地方。要添加连字符,最简单的方法是使用上面的字符类。

      【讨论】:

      • 对不起,我应该更清楚地重新描述我的原始问题,而不是仅仅链接到它。我需要单词边界不是 a-z、A-Z、0123456789 以及下划线和连字符。基本上,据我了解 \b 是如何工作的, \b 减去连字符。
      • @Halle \b 不是一个实际的字符,它是一个零宽度的断言。我认为只是在否定中添加一个字符是一个脆弱的解决方案,但当然,你会比我更了解你的数据。
      • 你是对的,我明白这是一个零宽度的断言。我要解决的问题是 \b 对于我的许多测试用例中的每个奇怪案例都是理想的,只有一个例外是 -cat 正在被替换。因此,如果我要使用 \b 以外的其他内容,我希望它针对每个其他单词边界向 \b 发出相同的结果,但不更改 -cat。
      • @Halle Word 边界出现在\w\W 字符之间,因此要添加连字符,请使用[\w-],正如我在最近的编辑中所建议的那样。你也可以使用(?&lt;!-)\b,不过我觉得这个版本更简洁。
      • 感谢您的回答和讨论,非常有帮助。
      猜你喜欢
      • 2012-08-22
      • 1970-01-01
      • 1970-01-01
      • 2015-10-20
      • 1970-01-01
      • 2010-12-05
      • 1970-01-01
      • 1970-01-01
      • 2012-03-07
      相关资源
      最近更新 更多