当我使用分组时,在Ruby正则表达式(regex)中如何使用gsub进行反向引用?

29

我希望能够修补从网页中提取出来的一些文本数据。 样例:

t="First sentence. Second sentence.Third sentence."

第二句话结尾的句点后面没有空格。这表明第三句话在原始文档中是单独一行(在 br 标签之后)。

我想使用这个正则表达式将 "\n" 字符插入到适当的位置并修补我的文本。 我的正则表达式:

t2=t.gsub(/([.\!?])([A-Z1-9])/,$1+"\n"+$2)

但不幸的是它并没有起作用:"NoMethodError: undefined method `+' for nil:NilClass"。我该如何正确地回溯到匹配的组?在Microsoft Word中这很容易,我只需要使用\1和\2符号。


2
当第二个参数被评估时,编号全局变量($1$2,...)未设置,它们由 gsub 在提交给块之前设置。因此,sawa建议在何时使用 '\1' 和何时使用 $1 - mu is too short
3个回答

34

在替换字符串中,你可以使用\1来引用反向引用(匹配第一组捕获内容)。

t = "First sentence. Second sentence.Third sentence!Fourth sentence?Fifth sentence."
t.gsub(/([.!?])([A-Z1-9])/, "\\1\n\\2") # => "First sentence. Second sentence.\nThird sentence!\nFourth sentence?\nFifth sentence."

26
  • 如果你使用gsub(regex, replacement),那么使用'\1''\2'等来引用匹配的内容。确保不要在replacement周围放双引号,否则需要像Joshua的回答中一样转义反斜杠。从'\1'到匹配的转换将在gsub内部完成,而不是通过字面解释。
  • 如果你使用gsub(regex){replacement},那么使用$1$2等来引用匹配的内容。

但对于你的情况,不使用匹配更容易:

t2 = t.gsub(/(?<=[.\!?])(?=[A-Z1-9])/, "\n")

1
他必须使用双引号才能获得换行符或 '\1' + "\n" + '\2' - mu is too short
@muistooshort,原始的代码中使用的是+,所以你提供的就是我想到的。 - sawa

8
如果您因Rubocop抱怨“避免使用Perl风格的反向引用”而到达此处,您可以尝试以下方法:将$1、$2等替换为\1、\2等。
some_id = $1
# or
some_id = Regexp.last_match[1] if Regexp.last_match

some_id = $5
# or
some_id = Regexp.last_match[5] if Regexp.last_match

它也希望您执行

%r{//}.match(some_string)

替代

some_string[//]

糟糕的 (Rubocop)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接