【问题标题】:equivalence of brace expansion within bash [[ compound command (test statement)bash [[ 复合命令(测试语句)中的大括号扩展等价
【发布时间】:2013-09-18 12:09:36
【问题描述】:

我希望foo() 符合extended regex 或类似brace expansion

基于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'

但是用于检测alternation / extended pattern 的适当格式是什么?

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

此外bash manpage 说:

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

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

【问题讨论】:

  • 您展示的以* 开头的示例都不是有效的正则表达式。
  • 哎呀,你是对的!好点@chepner。我在想那个模式是正则表达式的一个子集!我解决了我的问题,添加了信息/教育链接。谢谢你的警惕。干杯;-)

标签: regex bash conditional-operator brace-expansion


【解决方案1】:

您需要使用=~ 运算符。

来自man bash

一个额外的二元运算符 =~ 可用,具有相同的 优先级为 == 和 !=。使用时,右边的字符串 的运算符被认为是扩展的正则表达式 并进行相应的匹配。

试试这个:

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

另请注意,* 是通配符(并进行“模式匹配”),而 .* 是正则表达式。

将您的示例更改为:

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

【讨论】:

  • 这是错误的。 =~ 不检查它是否与模式匹配,它会检查此字符串是否包含与模式匹配的字符串。所以使用正则表达式.*(r|s) 应该为字符串asshole 返回true。使用^pattern$ 代替完全匹配
【解决方案2】:

你是说这个吗?

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

或使用 extglob:

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

更多信息你可以阅读bash hackers page about pattern matching

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-03-03
    • 1970-01-01
    • 2021-07-15
    • 1970-01-01
    • 2016-01-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多