CamelCase 单词的独立元素

CamelCase 单词的独立元素

有没有办法在文本的“内部”单词边界处拆分驼峰式单词?

例如,给定字符串:

IamHelloTest forYou PickTest; 

作为输入,我想产生作为输出:

Iam
Hello
Test
for
You
Pick
Test

更新:既然这个问题有很多有用的答案,我将如何继续包括以下案例?

输入:

IamTestECHO TEST PickFoo BARFull;

期望的输出:

I
am
Test
ECHO
TEST
Pick
Foo
Bar
FULL

更新:我将如何继续包含下划线?

输入:

IamTestECHO TEST PickFoo BARFull def_python_FunctionTwo;

期望的输出:

I
am
Test
ECHO
TEST
Pick
Foo
Bar
FULL
def
python
Function
Two

答案1

如果您的grep实现支持-o(并且不是 ast-open 实现,它会因-o与空字符串匹配的正则表达式而阻塞):

grep -o '[[:upper:]]*[[:lower:]]*'

答案2

通过 GNU grep,使用 Unicode 字符属性和零宽度断言:

grep -Po '((?<!=\p{Lu})\p{Lu}|(?<!=\pL)\pL)\p{Ll}*'

$ echo 'IamHelloTest forYou PickTest;' | grep -Po '((?<!=\p{Lu})\p{Lu}|(?<!=\pL)\pL)\p{Ll}*'
Iam
Hello
Test
for
You
Pick
Test
$ echo 'АямГеллоТест форЮ ПикТест' | grep -Po '((?<!=\p{Lu})\p{Lu}|(?<!=\pL)\pL)\p{Ll}*'
Аям
Гелло
Тест
фор
Ю
Пик
Тест

答案3

为了处理您的第二个示例,建议采用更“基于规则”的方法。考虑以下 Perl 脚本 ( camelcaseproc):

#!/usr/bin/perl -CSDA -p

s{  \W+                                     # break on non-word
 |  _                                       # break on "_"
 |  (?<=\p{Ll})(?=\p{Lu})                   # ...aB... → ...a-B...
 |  (?<=\p{Lu})(?=\p{Lu}\p{Ll})             # ..ABCd.. → ...AB-Cd.
 |  (?<=I)(?=am)                            # exceptions rules
 }{-}xg                                     # 
  • 第 1 行:使用 Unicode(处理重音、西里尔字母)
  • 第 2 行:用“\n”替换非字母
  • 第 3,4,5 行:break-intraWord 规则(由左上下文、右上下文定义)
  • 第 5 行:“Iam”的例外规则
  • 第 5 行:x选项可以在正则表达式中添加注释

通常chmod +x camelcaseproc我们可以将其用作:

$ camelcaseproc <<< "IamTestECHO TEST PickFoo BARFull"
I-am-Test-ECHO-TEST-Pick-Foo-BAR-Full

$ camelcaseproc input-file

$ echo "IamTestECHO TEST PickFoo BARFull" | camelcaseproc

答案4

sed

sed -Ee 's/([a-z])([A-Z])/\1\n\2/g' < your_file

grep

grep -Eo '[A-Z][a-z]+' < your_file

相关内容