KornShell 模式扩展了 POSIX shell“glob”模式(即*
、?
等),具有重复说明符(例如*(...)
、+(...)
)以及许多不错的功能之间的否定。
在一个 hobbist 项目中,我打算实现这些模式来进行字符串处理,而不是各种正则表达式变体,例如 BRE、ERE、JavaScript RegExp。我认为的一个主要好处是它在 C 字符串中不会那么冗长,因为在编写模式时可以避免使用反斜杠字符。
我对计算机科学的有限理解表明,KornShell 模式支持的功能使其符合常规语法的规范。
问题:这在技术上正确吗? (即使不是,我仍然认为这种子语言是有价值和令人向往的。)
答案1
是的,这是正确的,它可以符合正则表达式的条件,zsh 的扩展 glob glob 模式也是如此,它从常规扩展正则表达式有更直接的翻译:
埃雷 | 桀骜 | 克什93 |
---|---|---|
. |
? |
? |
x* |
x# |
*(x) |
x+ |
x## |
+(x) |
x{1,2} |
x(#c1,2) |
{1,2}(x) |
[...] |
[...] |
[...] |
(...) |
(...) |
@(...) |
a|b |
(a|b) |
@(a|b) |
^ |
(#s) |
无 1 |
$ |
(#e) |
无 1 |
x? |
(|x) |
?(x) |
\1 ² |
无² | \1 |
ksh93 的内置函数printf
甚至可以将正则表达式从一种方言翻译为另一种方言:
$ printf '%P\n' '^(x{1,3})?a+'
?({1,3}(x))+(a)*
$ printf '%R\n' '*(x)'
^(x)*$
ast-open 实现grep
有一个-K
/--ksh-regexp
来使用 ksh93 扩展 glob 模式进行匹配。
但我仍然会避免称呼它正则表达式因为这可能只会导致混乱。
1 尽管 glob 模式通常默认情况下是锚定的,或者在某些上下文中可以通过某些外部语法进行锚定,例如与开头锚定的模式${var/#pattern/replacement}
类似。${var/pattern/replacement}
² 标准 ERE 中没有反向引用,只有标准 BRE 中才有,尽管某些 ERE 引擎支持将其作为扩展。无论如何,zsh和ksh93都支持捕获匹配的各个部分并稍后回忆它($MATCH
/在 zsh 中$match[1]
使用(#m)
/启用,或在 ksh93 中使用/ (完全匹配,如's )/ ,具体取决于上下文。(#b)
\0
${.sh.match[0]}
sed
&
\1
${.sh.match[1]}