我有一个很长的文字,我想用空格替换点,但只在文本的中间。 例如:
Domain:...................google.com
我需要这个:
Domain: google.com
我发现这个正则表达式用一个空格替换点:
str.gsub!(/(?<=:)\.+(?=[^\.])/, ' ')
但这还不够,因为它产生了:
Domain: google.com
我需要保留与点一样多的空间。 你会如何解决它?
答案 0 :(得分:4)
你快到了,你的正则表达式很好,只需使用String#gsub
的块版本来计算替换的匹配长度:
▶ str = 'Domain:...................google.com'
#⇒ "Domain:...................google.com"
▶ str.gsub(/(?<=:)\.+(?=[^\.])/) { |m| ' ' * m.length }
#⇒ "Domain: google.com"
答案 1 :(得分:3)
如果您需要在您描述的上下文中执行此操作(使用:
分隔的键/值,其中值为域名),您只需使用:
> s='Domain:............www.google.com'
=> "Domain:............www.google.com"
> s.gsub(/(?<=[:.])\./, ' ')
=> "Domain: www.google.com"
因为域名不包含:
或连续点。
有关更一般的用法,请参阅@mudasobwa答案,或者您也可以这样做:
s.gsub(/(?:\G(?!\A)|\A[^:]*:\K)\./, ' ')
(如果\G
锚点与上一次匹配后的位置匹配,则强制下一个结果为连续的。)
答案 2 :(得分:1)
听起来你希望用一个句号之前或之后用空格替换一个句号,我假设在一串句点之前不一定有一个冒号。如果是这样,有两种方法可以做到这一点。
str = "Domain:...................google.com"
使用Enumerable#each_cons代替正则表达式
" #{str} ".each_char.each_cons(3).map { |before,ch,after|
ch=='.' && (before=='.' || after== '.') ? ' ' : ch }.join
#=> "Domain: google.com"
步骤如下。
s = " #{str} "
#=> " Domain:...................google.com "
a = s.each_char
#=> #<Enumerator: " Domain:...................google.com ":each_char>
e = a.each_cons(3)
#=> #<Enumerator: #<Enumerator: " Domain:...................google.com ":
# each_char>:each_cons(3)>
请注意e
如何被视为复合枚举器。我们可以通过将它转换为数组来查看此枚举器生成的元素。
e.to_a
#=> [[" ", "D", "o"], ["D", "o", "m"], ["o", "m", "a"], ["m", "a", "i"],
# ["a", "i", "n"], ["i", "n", ":"], ["n", ":", "."], [":", ".", "."],
# [".", ".", "."], [".", ".", "."], [".", ".", "."], [".", ".", "."],
# [".", ".", "."], [".", ".", "."], [".", ".", "."], [".", ".", "."],
# [".", ".", "."], [".", ".", "."], [".", ".", "."], [".", ".", "."],
# [".", ".", "."], [".", ".", "."], [".", ".", "."], [".", ".", "."],
# [".", ".", "."], [".", ".", "g"], [".", "g", "o"], ["g", "o", "o"],
# ["o", "o", "g"], ["o", "g", "l"], ["g", "l", "e"], ["l", "e", "."],
# ["e", ".", "c"], [".", "c", "o"], ["c", "o", "m"], ["o", "m", " "]]
继续,
b = e.map { |before,ch,after| ch=='.' && (before=='.' || after== '.') ? ' ' : ch }
#=> ["D", "o", "m", "a", "i", "n", ":", " ", " ", " ", " ", " ", " ", " ",
# " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", "g", "o",
# "o", "g", "l", "e", ".", "c", "o", "m"]
b.join
#=> "Domain: google.com"
使用正则表达式
r = /
(?<=\A|\.) # match the beginning of string or a period in a positive lookbehind
\. # match a period
| # or
\. # match a period
(?=\.|\z) # match a period or the end of the string
/x # free-spacing regex definition mode
str.gsub(r,' ')
#=> "Domain: google.com"