如何转换第一个字母为大写且其余为小写的字符串。

时间:2013-07-29 16:13:48

标签: tcl uppercase lowercase

例如,我有一句话:是什么,我们是谁的nUmBer?是iT 26。我必须将每个单词的第一个字母首先转换为大写,然后将小写单词转换为小写。我想使用所有 lsearch,lindex lreplace 和东西并形成代码。谁能告诉我怎么做?

3 个答案:

答案 0 :(得分:3)

string totitle命令关闭:它将整个字符串小写,除了第一个大写的字符。

set s {whAT is yOur hoUSe nUmBer ? Is iT 26.}
string totitle $s
What is your house number ? is it 26.

将每个单词大写更多参与:

proc CapitalizeEachWord {sentence} {
    subst -nobackslashes -novariables [regsub -all {\S+} $sentence {[string totitle &]}]
}
set s {whAT is yOur hoUSe nUmBer ? Is iT 26.}
CapitalizeEachWord $s
What Is Your House Number ? Is It 26.

regsub命令获取每个以空格分隔的单词,并将其替换为文字字符串“[string totitle word ]”:

"[string totitle whAT] [string totitle is] [string totitle yOur] [string totitle hoUSe] [string totitle nUmBer] [string totitle ?] [string totitle Is] [string totitle iT] [string totitle 26.]"

我们使用subst命令来评估所有单独的“string totitle”命令。

答案 1 :(得分:1)

将命令应用于字符串的一堆由常规表达式选择的子字符串的常用模型(在8.6及更低版本中)是这样的:

subst [regsub -all $REtoFindTheSubstrings [MakeSafe $input] {[TheCommandToApply &]}]

MakeSafe是必需的,因为subst不仅会执行所需的位。即使禁用了某些替换类(例如,使用-novariables),您仍然仍然需要最棘手的一项-命令替换-这意味着像hello[pwd]goodbye这样的字符串可以帮助您。为了解决这个问题,您可以通过用反斜杠版本替换每个Tcl 元字符(或至少是subst中重要的字符)来使字符串“安全”。这是MakeSafe的经典版本(您经常会看到内联):

proc MakeSafe {inputString} {
    regsub -all {[][$\\{}"" ]} $inputString {\\&}
}

以交互方式进行演示:

% MakeSafe {hello[pwd]goodbye}
hello\[pwd\]goodbye

在该版本中,尽管可以关闭变量,但无需在subst中关闭任何替换类,并且在应用该命令时也不会感到意外,因为在替换参数中可能会出现错误字符串已被转义。但是有一个很大的缺点:您可能需要在转换中更改正则表达式,以考虑到当前存在的额外反斜杠。问题的RE不需要它(因为它只是选择单词字符序列),实际上可以放心使用此简化版本:

subst [regsub -all {\w+} [regsub -all {[][\\$]} $input {\\&}] {[string totitle &]}]

从8.7开始,-command中有一个regsub选项可以避免所有这些麻烦。它也相当快,因为​​subst通过将其转换编译为字节码来工作(对于一次替代来说,这不是一个好选择!),而regsub -command使用直接命令调用,则更有可能快点。

regsub -all -command {\w+}  $input {string totitle}

regsub -all -command使用的内部方法可以在8.6(或更早的版本中使用更多的垫片)中进行模拟,但这是不平凡的:

proc regsubAllCommand {RE input command} {
    # I'll assume there's no sub-expressions in the RE in order to keep this code shorter
    set indices [regexp -all -inline -indices -- $RE $input]
    # Gather the replacements first to make state behave right
    set replacements [lmap indexPair $indices {
        # Safe version of:  uplevel $command [string range $input {*}$indexPair]
        uplevel 1 [list {*}$command [string range $input {*}$indexPair]]
    }]
    # Apply the replacements in reverse order
    set output $input
    foreach indexPair [lreverse $indices] replacement [lreverse $replacements] {
        set output [string replace $output {*}$indexPair $replacement]
    }
    return $output
}

regsub的C实现在内部使用工作缓冲区等,但这在Tcl级别上不太方便。

答案 2 :(得分:-1)

您可以使用Initcap功能将大写字母设为大写字母,然后以小写字母显示。