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

How to convert from snake_case to CamelCase (aka PascalCase) using TCL?

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

示例:

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

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

如果你有 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 中 regsub 有一个 -command 选项…

我不确定你为什么坚持使用 regsub,所以我只是忽略了那部分。使用 lmap 你可以用这样的一行来做到这一点:

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

这适用于 Tcl 8.6 及更高版本。对于早期版本,可以使用 lmap 的简单脚本实现。

I'm currently searching for _, removing it then replacing the following letter with toupper, but I'm hoping to find a more elegant solution.

您对输入的控制程度如何?输入是否保证具有某种形式?

如果它在你的控制之下,则不需要正则表达式,你可以使用 split and then run the transform using string totitle 通过 Tcl 列表绕道而行。观看:

% set name "not_so_simple"
% join [lmap el [split $name _] {string totitle $el}] ""
NotSoSimple

这将适用于从 8.6 开始的 Tcl。在下面,您将不得不使用就地循环来替换 lmap.