r = /
\b # Match a word break
[A-Z] # Match an upper-case letter
[a-z]+ # Match >= 1 lower-case letters
\- # Match hypen
\K # Forget everything matched so far
[a-z] # Match a lower-case letter
(?= # Begin a positive lookahead
[a-z]+ # Match >= 1 lower-case letters
\b # Match a word break
) # End positive lookahead
/x # Free-spacing regex definition mode
"Jean-paul Bertaud-alain".gsub(r) { |s| s.upcase }
#=> "Jean-Paul Bertaud-Alain"
"Jean de-paul Bertaud-alainM".gsub(r) { |s| s.upcase }
#=> "Jean de-paul Bertaud-alainM"
4条答案
按热度按时间z4iuyo4d1#
String#gsub
可以接受一个块参数,所以这很简单:或者,更简洁地说:
请注意,正则表达式
/-[a-z]/
只匹配a-z
范围内的字母,这意味着它不会匹配例如。à
。这是因为String#upcase
无论如何都不会尝试将带有变音符号的字符大写,因为大写是依赖于语言的(例如,i
在土耳其语中的大写与英语中的大写不同)。阅读此答案以了解更多信息:https://stackoverflow.com/a/4418681li9yvcax2#
yh2wf1be3#
我建议你通过要求字母大写来使测试更加苛刻:1)前面是一个大写的单词,后面是一个连字号; 2)后面是一个大写字母,后面是一个单词分隔符。
gojuced74#
我想到了这个:
.gsub(/(?<=-|\b)\p{L}/, &:upcase)
这会使任何Unicode字母在断字符或破折号后大写,所以这也适用于非ASCII字符: