我必须处理一段文本,其中某些字段中间可能有一些虚假的换行符。我想删除这些换行符(用空格替换它们),而不删除“有效”换行符,它们总是以 \t
开头。
所以,我想用一个空格替换所有前面没有制表符的换行符。为了让事情变得更复杂一点,如果换行符的两边都有一个空格,那么我想保留它。也就是说,这个
"one\ttwo\tbuckle my \nshoe\t\t\n"
会变成
"one\ttwo\tbuckle my shoe\t\t\n"
即,“我的”和“鞋子”之间有一个空格,而不是两个。
编辑 - 一些说明:不需要的换行符位于一段常规文本的中间。如果换行符出现的单词之间有空格,我想保留它。否则,我想添加一个。例如
"one\ttwo\tbuckle my \nshoe\t\t\n"
=> "one\ttwo\tbuckle my shoe\t\t\n"
"one\ttwo\tbuckle my\nshoe\t\t\n"
=> "one\ttwo\tbuckle my shoe\t\t\n"
"one\ttwo\tbuckle my \n shoe\t\t\n"
=> "one\ttwo\tbuckle my shoe\t\t\n"
编辑 2:我想出了一个笨拙但有效的解决方案。我对此不是很满意,双 gsubbing 看起来不够优雅。
>> strings = ["one\ttwo\tbuckle my\nshoe\t\t\n", "one\ttwo\tbuckle my \nshoe\t\t\n", "one\ttwo\tbuckle my \n shoe\t\t\n"]
=> ["one\ttwo\tbuckle my\nshoe\t\t\n", "one\ttwo\tbuckle my \nshoe\t\t\n", "one\ttwo\tbuckle my \n shoe\t\t\n"]
>> strings.collect{|s| s.gsub(/[^\t]\n\s?/){|match| match.gsub(/\s*\n\s*/," ")} }
=> ["one\ttwo\tbuckle my shoe\t\t\n", "one\ttwo\tbuckle my shoe\t\t\n", "one\ttwo\tbuckle my shoe\t\t\n"]
考虑到我现在对添加/保留空格的扩展要求,这似乎比下面的任何建议都有效。
最佳答案
没有后视选项
你可以匹配:
(\G|[^\t])\n
并替换为第 1 组匹配的反向引用。
这是一个 Ruby 片段 ( as seen on ideone.com ):
from = "\none\ttwo\tbuckle my \nshoe\t\t\nx\n\n\t\n\n"
to = "one\ttwo\tbuckle my shoe\t\t\nx\t\n"
mod = from.gsub(/(\G|[^\t])\n/, '\1')
puts (mod == to) # true
本质上,我们要么匹配不是 \t
的“something”,然后是 \n
,然后仅替换为“something”部分(有效地保留任何“它"是,但删除 \n
),或者我们可以简单地使用 \G
从上一个匹配继续,以允许 \n
在字符串的开头或后面另一个已删除的 \n
。
引用资料
后视选项
如果flavor支持lookbehind,还可以匹配:
(?<!\t)\n
并简单地替换为空字符串。
引用资料
关于ruby - 正则表达式问题 - 用空格替换所有前面没有制表符的换行符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3439472/