我想在Ruby中进行字符串替换,但仅当某些条件 不符合时才会进行。
当行不以#include
语句开头时,将'allegro4'的所有出现替换为'allegro'。我试过这个,但我没有成功。替换根本就没有完成。
"#include <allegro4/allegro4.h>".gsub(/(?!#include) allegro4/, 'allegro')
在irb
中查看负向前瞻和尝试不同事物的其他示例,让我相信,在字符串的开头专门用负面预测会有一些奇怪的事情发生。
答案 0 :(得分: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>"