正则表达式:匹配 btn 但不匹配 .btn

Regex: match btn but not .btn

在升级旧 bootstrap 版本的过程中,我很难想出正确的正则表达式来处理我的 classes 在 HAML 代码中编写的各种方式。

以下是 .btn class 如何出现在我的代码中的一些示例:

%a.btn.btn-primary

= f.submit "Save", class: "btn btn-primary"

在迁移 Ruby 脚本中,我可以很容易地通过以下行修复第一个版本(haml_string 是包含我的行的变量):

haml_string.gsub(/(.*)\.btn\s(.*)/, '.btn .btn-default ')

但我正在努力修复第二个版本,尤其是第一个版本已经 运行。我已经尝试了以下事情(消极展望,看看我们是否以某种方式匹配我们已经在之前 运行:

中修复的 .btn 版本
haml_string.gsub(/btn\s(?<!\.btn)/, 'btn btn-default ')

也许我只是站在浴缸边上,但这对我作为一个普通的正则表达式用户来说似乎并不平凡......任何提示都将不胜感激!

您的正则表达式 btn\s(?<!\.btn) 无效,因为负向回顾 (?<!\.btn) 是 运行 after btn and 一个 whitespace 字符被匹配。考虑一个 btn 123 字符串: btn 被匹配,然后 space 被匹配,lookbehind returns true 因为 btn 不等于 .btn.

要使您的 模式起作用(在某种程度上),您可以将回顾移动到 \s 之前:btn(?<!\.btn)\s。在这种情况下,在匹配 btn 之后,正则表达式引擎会确保紧邻当前位置的左侧没有 .btn

但是,您的模式看起来好像您想匹配 btn 作为一个完整的单词。 因此,我建议通过以下方式修复模式(参见 demo):

/\bbtn\b(?<!\.btn)/

或者,让它更短一些(已经 ):

/(?<!\.)\bbtn\b/

参见 this regex demo。请注意,此版本更有效,因为它必须匹配 btn 仅当 . 之前没有出现(它不必检查单词边界和非出现的 btn匹配上下文)。

如果您想了解有关定位回顾的更多详细信息,请参阅 the "Positioning the Lookaround" section at rexegg.com

图案详情

  • (?<!\.) - 如果 . 立即出现在当前位置
  • 的左侧,则匹配失败的负面回顾
  • \b - 单词边界
  • btn - 一个btn
  • \b - 单词边界。