1

我希望foo()符合扩展的正则表达式大括号扩展

解决方案基于egrep

foo() 
{
  egrep -sq "$2" <<< "$1" && echo "string '$1' matches pattern '$2'"
}

$ foo bar '.*r'
string 'bar' matches pattern '*r'
$ foo bar '.*r|.*s'
string 'bar' matches pattern '*r|*s'

但我也想要一个 100% 的bash解决方案。我的尝试:

foo() 
{
  [[ "$1" = $2 ]] && echo "string '$1' matches pattern '$2'"
}

基本模式没问题:

$ foo bar '*r'
string 'bar' matches pattern '*r'

但是用于检测交替/扩展模式的适当格式是什么?

$ foo bar '*(r|s)'
$ foo bar '*\(r|s\)'
$ foo bar '*\(r\|s\)'
$ foo bar '*\{r,s\}'
$ foo bar '*{r,s}'

此外bash,联机帮助页说:

[[表达式]]
对[[和]]之间的词不进行分词和路径名扩展;执行波浪号扩展、参数和变量扩展、算术扩展、命令替换、进程替换和引号删除。

  1. [[ ]]在语句中使用扩展的正则表达式/模式有技巧吗?
  2. 你将如何实现这样的功能?
4

2 回答 2

2

您需要使用=~运算符。

来自man bash

额外的二元运算符 =~ 可用,其优先级与 == 和 != 相同。使用时,运算符右侧的字符串被视为扩展正则表达式并进行相应匹配。

尝试这个:

foo() 
{
  [[ "$1" =~ $2 ]] && echo "string '$1' matches pattern '$2'"
}

另请注意,这*是一个通配符(并经历“模式匹配”),而.*它是一个正则表达式。

将您的示例更改为:

$ foo bar '.*(r|s)'
string 'bar' matches pattern '.*(r|s)'
于 2013-09-18T12:21:26.747 回答
1

你是这个意思?

[[ 'bar' == *[rs] ]] && echo yes || echo no # this is simple globbing

或使用 extglob:

shopt -s extglob
[[ 'bar' == @(*r|*s) ]] && echo yes || echo no

有关更多信息,您可以阅读有关模式匹配的 bash 黑客页面

于 2013-09-18T12:20:29.033 回答