理想情况下,我正在寻找一种单行regsub
或类似方法,以使用CamelCase将字符串变量$name
从snake_case转换为另一个字符串变量$class_name
。
示例:
"simple" -> "Simple"
"not_so_simple" -> "NotSoSimple"
我目前正在搜索_
,将其删除,然后将下面的字母替换为toupper
,但我希望找到一个更优雅的解决方案。
答案 0 :(得分:2)
我当前正在搜索_,将其删除然后替换为 以下与toupper一起写信,但我希望能找到一个更优雅的 解决方案。
您对输入有多少控制权?输入是否保证具有某种形式?
如果它在您的控制之下,则不需要正则表达式,您可以使用split
通过Tcl列表绕行,然后使用string totitle
运行转换。观看:
% set name "not_so_simple"
% join [lmap el [split $name _] {string totitle $el}] ""
NotSoSimple
这将在Tcl中从8.6起开始工作。在下面,您将不得不使用就地循环来替换lmap
。
答案 1 :(得分:1)
如果您拥有Tcl 8.7(目前在alphas / development中),那么使用命令替换并不难:
regsub -all -command {(?:^|\W|_)[a-z]} $string {apply {match {
string toupper [string trimleft $match "_"]
}}} string
(适用于您的两个用例。)
在早期版本中,它有点混乱:
# NB: do replacements from back to front so indices remaining to be replaced are still valid
foreach range [lreverse [regexp -all -inline -indices {(?:^|\W|_)[a-z]} $string]] {
set match [string range $string {*}$range]
set replacement [string toupper [string trimleft $match "_"]]
set string [string replace $string {*}$range $replacement]
}
您也可以使用regsub
和subst
来欺骗,但是我发现写起来要困难得多(我必须进行更彻底的测试!)。这就是为什么在8.7中为-command
提供regsub
选项的原因……
答案 2 :(得分:1)
我不确定您为什么坚持使用regsub
,所以我只是忽略了这一部分。使用lmap
,您可以像这样用一行来完成此操作:
join [lmap s [split $str _] {string totitle $s}] ""
这在Tcl 8.6及更高版本中有效。对于较早的版本,可以使用lmap
的简单的仅脚本实现。