我正在尝试将<p>
标记添加到用户生成的文本中,而不是换行符。
这是我的代码:
string.gsub(/(.*)[\n\r\Z$]+/, "<p>\\1</p>")
替换完全按照第一段的预期工作,但如果我添加额外的回车,它只包装最后的文本块。似乎\Z
和$
与我期望的不匹配。
我做错了什么?
此:
Lorem ipsum dolor sit amet.
\n
Vestibulum laoreet erat id quam.
变成这样:
<p>Lorem ipsum dolor sit amet.</p>
Vestibulum laoreet erat id quam.
但是这个:
Lorem ipsum dolor sit amet.
\n
Vestibulum laoreet erat id quam.
\n
变成这样:
<p>Lorem ipsum dolor sit amet.</p>
<p>Vestibulum laoreet erat id quam.</p>
答案 0 :(得分:1)
尝试使用正则表达式
/\A((?:.|[\n\r])+)\Z/
并替换为\\1
您当前的正则表达式与输入字符串中的最后一个换行符/托架字符匹配,\Z
甚至无效。 $
是字符类中的文字字符。
如果您的意思是想要在<p>
和</p>
之间换行,那么您只需使用:
/^(.+)$/
并替换为\\1
或者使用正则表达式:
/([^\n\r]+)/
答案 1 :(得分:1)
我会这样做:
ary = [
"Lorem ipsum dolor sit amet.\nVestibulum laoreet erat id quam.",
"Lorem ipsum dolor sit amet.\nVestibulum laoreet erat id quam.\n"
]
puts ary.map{ |a|
a.scan(/.+$/).map{ |s| "<p>#{s}</p>" }
}
# >> <p>Lorem ipsum dolor sit amet.</p>
# >> <p>Vestibulum laoreet erat id quam.</p>
# >> <p>Lorem ipsum dolor sit amet.</p>
# >> <p>Vestibulum laoreet erat id quam.</p>
两个字符串都以相同的方式返回。
正则表达式不是魔术棒,你可以挥手解决每个问题。他们有自己的用途,但是有太多人认为他们是解决大多数问题的正确工具,但事实并非如此。此外,人们认为模式越复杂,它就越有可能解决问题,但复杂性为垃圾提供了更多的压缩空间,所以请保持简单。
此代码:
a.scan(/.+$/).map{ |s| "<p>#{s}</p>" }
依赖String的scan
查看字符串并返回所有“\ n”终止行。如果该行不以“\ n”结尾,则返回它也是因为它是字符串的最后部分。 scan
返回一个匹配数组,因此,在这种特殊情况下,这是一个由EOL终止的字符串片段数组,带有一个可能的尾随字符串片段。
将这些内容传递到map
以将字符串片段嵌入<p>...</p>
中,然后就完成了。
另一种完成同样事情的方法是利用字符串的gsub
和块:
puts ary.map{ |a|
a.gsub(/.+$/) { |s| "<p>#{s}</p>" }
}
# >> <p>Lorem ipsum dolor sit amet.</p>
# >> <p>Vestibulum laoreet erat id quam.</p>
# >> <p>Lorem ipsum dolor sit amet.</p>
# >> <p>Vestibulum laoreet erat id quam.</p>
对于与模式匹配的每个实例,gsub
会将匹配的文本传递给块。从那里开始,这是另一个简单的字符串插值。