Ruby 正则表达式消除新行直到 .要么 ?或大写字母
Ruby regex eliminate new line until . or ? or capital letter
我想用我的琴弦做以下事情:
line1= "You have a house\nnext to the corner."
如果句子在点或问号或大写字母后没有换行结束,则消除 \n
,因此在这种情况下所需的输出将是:
"You have a house next to the corner.\n"
再举一个例子,这次是问号:
"You like baggy trousers,\ndon't you?
应该变成:
"You like baggy trousers, don't you?\n".
我试过:
line1.gsub!(/(?<!?|.)"\n"/, " ")
(?<!?|.)
\n 之前不能有问号(?)或逗号
但我收到以下语法错误:
SyntaxError: (eval):2: target of repeat operator is not specified: /(?<!?|.)"\n"/
对于中间有大写字母的句子,在大写字母前加一个\n,所以句子:
"We were winning The Home Secretary played a important role."
应该变成:
"We were winning\nThe Home Secretary played a important role."
你快到了。您需要 a) 转义 ?
和 .
和 b) 删除表达式中 \n
周围的引号:
line1= "You have a house\nnext to the corner.\nYes?\nNo."
line1.gsub!(/(?<!\?|\.)\s*\n\s*/, " ")
#⇒ "You have a house next to the corner.\nYes?\nNo."
如你所愿的尾部\n
,后面加上即可:
line1.gsub! /\Z/, "\n"
#⇒ "You have a house next to the corner.\nYes?\nNo.\n"
实现此目的的简单方法是用 space 替换所有嵌入的换行符,这样可以有效地连接线段,然后修复行尾。没有必要担心标点符号,也没有必要使用(或维护)正则表达式。
你可以用很多方法来做到这一点,但我会使用:
sentences = [
"foo\nbar",
"foo\n\nbar",
"foo\nbar\n",
]
sentences.map{ |s| s.gsub("\n", ' ').squeeze(' ').strip + "\n" }
# => ["foo bar\n", "foo bar\n", "foo bar\n"]
下面是 map
块中发生的事情:
s # => "foo\nbar", "foo\n\nbar", "foo\nbar\n"
.gsub("\n", ' ') # => "foo bar", "foo bar", "foo bar "
.squeeze(' ') # => "foo bar", "foo bar", "foo bar "
.strip # => "foo bar", "foo bar", "foo bar"
+ "\n"
注意:答案并不意味着提供一种通用的方法来删除句子中不必要的换行符,它只是为了服务于 OP 目的,只删除或插入换行符字符串中的特定位置。
由于在不同的场景下需要以不同的方式替换匹配项,因此您应该考虑采用两步法。
.gsub(/(?<![?.])\n/, ' ')
这个将替换所有没有以 ?
和 .
开头的换行符(因为 (?<![?.])
是一个否定的后视,如果在当前的之前有一个子模式匹配,则匹配失败字符串内的位置)。
第二步是
.sub(/(?<!^) *+(?=[A-Z])/, '\n')
或
.sub(/(?<!^) *+(?=\p{Lu})/, '\n')
它将匹配不在行首的 0+ spaces ( *+
)(当然,不会回溯到 space 模式)(由于(?<!^)
negative lookbehind,将 ^
替换为 \A
以匹配整个字符串的开头),然后是一个大写字母((?=\p{Lu})
是一个正 lookahead,需要在当前位置右侧出现的图案)。
我想用我的琴弦做以下事情:
line1= "You have a house\nnext to the corner."
如果句子在点或问号或大写字母后没有换行结束,则消除 \n
,因此在这种情况下所需的输出将是:
"You have a house next to the corner.\n"
再举一个例子,这次是问号:
"You like baggy trousers,\ndon't you?
应该变成:
"You like baggy trousers, don't you?\n".
我试过:
line1.gsub!(/(?<!?|.)"\n"/, " ")
(?<!?|.)
\n 之前不能有问号(?)或逗号
但我收到以下语法错误:
SyntaxError: (eval):2: target of repeat operator is not specified: /(?<!?|.)"\n"/
对于中间有大写字母的句子,在大写字母前加一个\n,所以句子:
"We were winning The Home Secretary played a important role."
应该变成:
"We were winning\nThe Home Secretary played a important role."
你快到了。您需要 a) 转义 ?
和 .
和 b) 删除表达式中 \n
周围的引号:
line1= "You have a house\nnext to the corner.\nYes?\nNo."
line1.gsub!(/(?<!\?|\.)\s*\n\s*/, " ")
#⇒ "You have a house next to the corner.\nYes?\nNo."
如你所愿的尾部\n
,后面加上即可:
line1.gsub! /\Z/, "\n"
#⇒ "You have a house next to the corner.\nYes?\nNo.\n"
实现此目的的简单方法是用 space 替换所有嵌入的换行符,这样可以有效地连接线段,然后修复行尾。没有必要担心标点符号,也没有必要使用(或维护)正则表达式。
你可以用很多方法来做到这一点,但我会使用:
sentences = [
"foo\nbar",
"foo\n\nbar",
"foo\nbar\n",
]
sentences.map{ |s| s.gsub("\n", ' ').squeeze(' ').strip + "\n" }
# => ["foo bar\n", "foo bar\n", "foo bar\n"]
下面是 map
块中发生的事情:
s # => "foo\nbar", "foo\n\nbar", "foo\nbar\n"
.gsub("\n", ' ') # => "foo bar", "foo bar", "foo bar "
.squeeze(' ') # => "foo bar", "foo bar", "foo bar "
.strip # => "foo bar", "foo bar", "foo bar"
+ "\n"
注意:答案并不意味着提供一种通用的方法来删除句子中不必要的换行符,它只是为了服务于 OP 目的,只删除或插入换行符字符串中的特定位置。
由于在不同的场景下需要以不同的方式替换匹配项,因此您应该考虑采用两步法。
.gsub(/(?<![?.])\n/, ' ')
这个将替换所有没有以 ?
和 .
开头的换行符(因为 (?<![?.])
是一个否定的后视,如果在当前的之前有一个子模式匹配,则匹配失败字符串内的位置)。
第二步是
.sub(/(?<!^) *+(?=[A-Z])/, '\n')
或
.sub(/(?<!^) *+(?=\p{Lu})/, '\n')
它将匹配不在行首的 0+ spaces ( *+
)(当然,不会回溯到 space 模式)(由于(?<!^)
negative lookbehind,将 ^
替换为 \A
以匹配整个字符串的开头),然后是一个大写字母((?=\p{Lu})
是一个正 lookahead,需要在当前位置右侧出现的图案)。