有没有办法在文本的“内部”单词边界处拆分驼峰式单词?
例如,给定字符串:
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