如何使用TCL将snake_case转换为CamelCase(又名PascalCase)?

时间:2019-09-13 09:43:48

标签: tcl

理想情况下,我正在寻找一种单行regsub或类似方法,以使用CamelCase将字符串变量$name从snake_case转换为另一个字符串变量$class_name

示例:

"simple" -> "Simple"
"not_so_simple" -> "NotSoSimple"

我目前正在搜索_,将其删除,然后将下面的字母替换为toupper,但我希望找到一个更优雅的解决方案。

3 个答案:

答案 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]
}

您也可以使用regsubsubst来欺骗,但是我发现写起来要困难得多(我必须进行更彻底的测试!)。这就是为什么在8.7中为-command提供regsub选项的原因……

答案 2 :(得分:1)

我不确定您为什么坚持使用regsub,所以我只是忽略了这一部分。使用lmap,您可以像这样用一行来完成此操作:

join [lmap s [split $str _] {string totitle $s}] ""

这在Tcl 8.6及更高版本中有效。对于较早的版本,可以使用lmap的简单的仅脚本实现。