我有一个像 ImageWideNice
或者 ImageNarrowUgly
这样的驼峰字符串。现在我想将这个字符串分解成子字符串,如 Image
、Wide
或 Narrow
和 Nice
或 Ugly
。
我认为可以通过以下方式简单地解决:
camelCaseString =~ /(Image)((Wide)|(Narrow))((Nice)|(Ugly))/
但奇怪的是,这样只会填充$1
和$2
,而不是$3
。
你有更好的方法来拆分这个字符串吗?
s = 'nowIsTheTime'
s.split /(?=[A-Z])/
=> ["now", "Is", "The", "Time"]
?=pattern
是正向先行断言的一个例子。它会匹配字符串中 pattern 之前的位置,但不会消耗这些字符,也就是说,它并不包括 pattern 在匹配结果中。下面是另一个例子:
irb> 'streets'.sub /t(?=s)/, '-'
=> "stree-s"
s
被匹配(只有第二个t
匹配),但没有被替换。感谢@Bryce和他的regexp doc link。
Bryce Anderson提供了以下解释:在
()
匹配组的开头使用?=
被称为正向预查,这只是一种说法,即虽然正则表达式在确定是否匹配时正在查看字符,但它们不是匹配的一部分。split()
通常会忽略中间的字符,但在这种情况下,匹配本身是空的,因此没有任何东西。
reject {|x| x.empty? }
。 - Ollie Saunders我知道这个回答可能有些过时了,但对于其他人可能仍然有用。在Rails中,你可以这样做:"NowIsTheTime".underscore.humanize
DigitalRoss的答案是正确的,因为它处理了一般情况,即您不知道它是严格的驼峰命名(第一个字符小写)还是帕斯卡命名(第一个字母大写)。
如果您知道字符串以哪种形式存在,或者您想强制使用其中之一,Inflector可以实现。
对于帕斯卡命名:
"NowIsTheTime".titleize
对于驼峰命名法:
"nowIsTheTime".titleize.camelize :lower
#titleize
和#camelize
是严格属于Rails方法,而不是核心Ruby。 - onebreeI/p:- "ImageWideNice".scan(/[A-Z][a-z]+/).join(",")
O/p:- "Image,Wide,Nice"
虽然这是一个关于Ruby正则表达式的问题,而且DigitalRoss的答案正确且简单易懂,但我想再添加一个Java的答案:
// this regex doesn't work perfect with Java and other regex engines
"NowIsTheTime".split("(?=[A-Z])"); // ["", "Now", "Is", "The", "Time"]
// this regex works with first uppercase or lowercase characters
"NowIsTheTime".split("(?!(^|[a-z]|$))"); // ["Now", "Is", "The", "Time"]
"nowIsTheTime".split("(?!(^|[a-z]|$))"); // ["now", "Is", "The", "Time"]
camelCaseString =~ /(Image)(Wide|Narrow)(Nice|Ugly)/
?
DigitalRoss的答案不会识别嵌入在驼峰命名法中的缩写词。例如,它将把"MyHTMLTricks"分成"My H T M L Tricks"而不是"My HTML Tricks"。
这里有另一个选项,基于PmWiki中的AsSpaced()
函数,它非常敏感于这种情况:
"MyHTMLTricks" \
.gsub(/([[:lower:]\\d])([[:upper:]])/, '\1 \2') \
.gsub(/([^-\\d])(\\d[-\\d]*( |$))/,'\1 \2') \
.gsub(/([[:upper:]])([[:upper:]][[:lower:]\\d])/, '\1 \2')
=> "My HTML Tricks"
"MyHTMLTricks" \
.gsub(/([[:lower:]\\d])([[:upper:]])/, '\1 \2') \
.gsub(/([^-\\d])(\\d[-\\d]*( |$))/,'\1 \2') \
.gsub(/([[:upper:]])([[:upper:]][[:lower:]\\d])/, '\1 \2') \
.split
=> ["My", "HTML", "Tricks"]
记录一下,这是来自PmWiki的原始PHP代码。
function AsSpaced($text) {
$text = preg_replace("/([[:lower:]\\d])([[:upper:]])/", '$1 $2', $text);
$text = preg_replace('/([^-\\d])(\\d[-\\d]*( |$))/', '$1 $2', $text);
return preg_replace("/([[:upper:]])([[:upper:]][[:lower:]\\d])/", '$1 $2', $text);
}
def solution(string)
final_str = []
string.chars.each do |x|
final_str << " " if x.upcase == x
final_str << x
end
final_str.join
end
ThisIsANarrowImageOfHIV
做什么?与 n 进行连接,还是将 HIV 分割? - Andrew Grimm