我想用我的字符串做以下事情:
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之前的 (?<!?|.)
\ 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."
答案 0 :(得分:1)
你快到了。您需要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"
答案 1 :(得分:1)
这样做的简单方法是用空格替换所有嵌入的新行,这有效地连接线段,然后修复线端。没有必要担心标点符号,并且没有必要使用(或维护)正则表达式。
你可以通过很多方式实现这一目标,但我会使用:
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"
答案 2 :(得分:1)
注意:答案并不是要提供一种删除句子中不必要的换行符号的通用方法,它只是为了OP目的,只删除或插入字符串中特定位置的换行符
由于您需要以不同方式替换不同场景中的匹配,因此您应该考虑采用两步法。
.gsub(/(?<![?.])\n/, ' ')
这一行将替换所有不在?
和.
之前的换行符(如果在当前位置之前存在子模式匹配,则(?<![?.])
是否为匹配导致失败的匹配字符串)。
第二步是
.sub(/(?<!^) *+(?=[A-Z])/, '\n')
或
.sub(/(?<!^) *+(?=\p{Lu})/, '\n')
它将匹配0+空格( *+
)(占有率,没有回溯到空间模式中)不在行的开头(由于(?<!^)
负面的后观,替换{{ 1}} ^
匹配整个字符串的开头),然后跟一个大写字母(\A
是一个正向前瞻,需要一个模式出现在当前位置之后右)。