将西里尔字母大写中除第一个(大写)字母以外的所有字母小写

将西里尔字母大写中除第一个(大写)字母以外的所有字母小写

使除第一个字母之外的所有字母都小写。我更改后,第一个字母看起来像“大写”(从西里尔字母的大写)。其余部分(非大写)保持不变。

抱歉,这是西里尔文。例如 АБРАЗИЯ Абразия

我发出了正确的一般命令:

:%s/\<\u\zs\u*/\L&/g

但这没有用

我的 Linux 是 Gentoo,我的语言环境是 echo $LANG en_US.UTF-8。

我也尝试过:

 %s/\<[А-Я]\zs\[А-Я][а-я]*...

我不知道如何正确使用这个语法。我想这可能会起作用。

我不明白,即使之后

:se noic /[[:upper:]] 

不起作用。一定是语言环境的问题(我想知道)。

sed -n '322p' geod.txt | cut -f 1 -d " " 
АВГИТИТ—
sed -n '322p' geod.txt | cut -f 1 -d " " | xxd
0000000: d090 d092 d093 d098 d0a2 d098 d0a2 e280

尽管所有字母的 Unicode 编号大小相同。

我又重新检查了一遍:

file -bi geod.txt
text/plain; charset=utf-8

所以使用 utf-8 就可以了(尽管“文件”可能会出错)。

这是我的源文件: http://bpaste.net/show/140967/

答案1

编辑:vim由于对于是否应该使用或sed应该使用存在一些困惑。我为两者提供解决方案:

维姆

以下替换将单词替换为小写字符(第一个字母除外)。单字母单词将转换为大写。

:%s/\<\(\k\)\(\k*\)\>/\u\1\L\2/g

\k匹配字母数字字符和_.广泛使用的\w等效于[A-Za-z0-9_]西里尔字母,但在西里尔字母上会失败。

\<抓取\>单词边界,括号将匹配项分组为第一个字母和其余字母,分别使用\1和检索\2

要使此模式发挥作用,您需要将 vim 设置为使用 UTF-8。

set encoding=utf-8

塞德

sed 's/\b\([[:alpha:]]\)\([[:alpha:]]*\)\b/\u\1\L\2/g' <inputfile>

\b匹配 中的单词边界sed,其余与版本相同vim。 (在 GNU sed 上测试,字符类可能并非在所有sed版本中都受支持。)

答案2

这可以使用正则表达式来完成,现有的答案很好地涵盖了该方法,但还有另一种方法。

对于单个单词,只需移至该单词的第一个字母并使用:

lgue

要执行多个单词,您需要使用宏

qqlguewq

我将对此进行分解:

  • qq-- 开始录制一个名为q
  • l(这是一个小写的 L)——向右移动一个字符
  • gue-- 将每个字符小写(即gu)到当前单词的末尾 ( e)
  • w-- 转到下一个单词的第一个字符
  • q-- 停止录制宏

您可以使用 来调用宏@q。您可以使用 调用它九次9@q,或者使用 调用它四十二次42@q。对于这个特定的宏,可以安全地调用它任意次数——因此您可以使用9999@q.

另一种路线是递归宏:

qqqqqlguew@qq
  • qqq-- 开始录制q宏,然后立即停止录制,有效地清空该寄存器
  • @q-- 调用q宏,现在是空白的,但会不是一旦你停止录制宏
  • 其余部分的行为如上

当宏到达文档中最后一个单词的末尾时,它将退出(对于任何此类错误都会退出 - 否则它将永远继续)。

相关内容