我有一个这样的字符串:
"Jim-Bob's email @@@hl@@@address@@@endhl@@@ is: jb@example.com"
除了@@@
分隔符之外,我想替换所有非单词字符(符号和空格)。
我目前正在使用:
str.gsub(/[^\w@]+/, 'X')
产生:
"JimXBobXsXemailX@@@hl@@@address@@@endhl@@@XisXjb@exampleXcom"
在实践中,这已经足够了,但它有两个原因让我感到不快:
@
未被替换。[^\w]
代替\W
感觉很草率。如何替换所有非单词字符,除非这些字符组成@@@hl@@@
或@@@endhl@@@
分隔符字符串?
答案 0 :(得分:2)
str.gsub(/(@@@.*?@@@|\w+)|./) { $1 || "X" }
# => "JimXBobXsXemailX@@@hl@@@address@@@endhl@@@XisXXjbXexampleXcom"
这种方法使用交替工作类似于case
结构的事实:第一个匹配的消耗相应的字符串,然后不再对其进行匹配。因此,@@@.*?@@@
将消耗一个标记(如@@@hl@@@
;其中没有其他内容匹配。我们还匹配任何单词字符序列。如果捕获了其中任何一个,我们可以将它们返回为 - 是($1
)。如果没有,那么我们匹配任何其他字符(即不在标记内,而不是单词字符),并将其替换为"X"
。
答案 1 :(得分:1)
关于你的第二点,我认为你问的太多了;没有简单的方法可以避免这种情况。
关于第一点,一个简单的方法是暂时用您永远不会使用的字符替换"@@@"
(假设您使用的系统没有"\r"
,因此不使用该字符;我们可以将其用作时间替代品。)
"Jim-Bob's email @@@hl@@@address@@@endhl@@@ is: jb@example.com"
.gsub("@@@", "\r").gsub(/[^\w\r]/, "X").gsub("\r", "@@@")
# => "JimXBobXsXemailX@@@hl@@@address@@@endhl@@@XisXXjbXexampleXcom"