【问题标题】:Negative lookahead -- At the begining of the string负前瞻——在字符串的开头
【发布时间】:2017-03-27 14:15:01
【问题描述】:

我想在 Ruby 中进行字符串替换,但前提是满足某些条件。

当行不以#include 语句开头时,将所有出现的“allegro4”替换为“allegro”。我试过这个,但我没有任何成功。替换根本没有完成。

"#include <allegro4/allegro4.h>".gsub(/(?!#include) allegro4/, 'allegro')

查看其他负前瞻示例并在 irb 中尝试不同的事情让我相信,特别是在字符串开头的负前瞻有一些奇怪的事情发生。

【问题讨论】:

  • 你有什么问题?

标签: ruby regex negative-lookahead


【解决方案1】:
R = /
    \A              # match beginning of string
    (?!\#include)   # do not match '#include' at start of string (negative lookahead)
    .*?             # match any number of any character
    <               # match '<'
    \K              # forget everything matched so far
    allegro         # match string
    (\d+)           # match one or more digits in capture group 1
    \/allegro       # match string
    \1              # match the contents of capture group 1
    /x              # Free-spacing regex definition mode

def replace_unless(str)
  str.gsub(R, 'allegro/allegro') 
end

replace_unless "cat #include <allegro4/allegro4.h>"
  #=> "cat #include <allegro/allegro.h>" 
replace_unless "cat #include <allegro4/allegro3.h>"
  #=> "cat #include <allegro4/allegro3.h>"
replace_unless "#include <allegro4/allegro4.h>"
  #=> "#include <allegro4/allegro4.h>" 

我假设要匹配特定的字符串“allegro”,并且任何非负整数都可以跟在“allegro”的两个实例之后,但是在“allegro”的两个实例之后不能有不同的数字。如果数字必须是4,请将正则表达式中的(\d+)\1 替换为4。如果 'allegro' 只是任何小写字母字符串的替代,则正则表达式可以更改如下。

R = /
    \A              # match beginning of string
    (?!\#include)   # do not match '#include' at start of string (negative lookahead)
    .*              # match any number of any character
    <               # match character
    \K              # forget everything matched so far
    ([[:lower:]]+)  # match one or more lower-case letters in capture group 1
    (\d+)           # match one or more digits in capture group 2
    \/              # match character
    \1              # match the contents of capture group 1
    \2              # match the contents of capture group 2
    /x              # Free-spacing regex definition mode

def replace_unless(str)
  str.gsub(R, '\1/\1') 
end

replace_unless "cat #include <cats9/cats9.h>"
  #=> "cat #include <cats/cats.h>" 
replace_unless "dog #include <dogs4/dogs3.h>"
  #=> "dog #include <dogs4/dogs3.h>" 
replace_unless "#include <pigs4/pigs4.h>"
  #=> "#include <pigs4/pigs4.h>" 

【讨论】:

    猜你喜欢
    • 2020-08-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-27
    • 2020-06-11
    相关资源
    最近更新 更多