强制Bash使用Perl RegEx Engine


11

您可能已经知道,Bash RegEx引擎不支持现代RegEx引擎支持的许多功能(向后引用,环视断言等)。以下是我刚刚创建的一个简单的Bash脚本,试图解释我的最终目标是:

#!/bin/bash

# Make sure exactly two arguments are passed.
if [ $# -lt 2 ]
then
    echo "Usage: match [string] [pattern]"
    return
fi

variable=${1}
pattern=${2}

if [[ ${variable} =~ ${pattern} ]]
then
    echo "true"
else
    echo "false"
fi

因此,例如,类似以下命令的内容将返回false:

. match.sh "catfish" "(?=catfish)fish"

而在Perl或JavaScript正则表达式测试器中使用时,完全相同的表达式将找到匹配项。

反向引用(例如(expr1)(expr2)[] \ 1 \ 2)也将不匹配。

我得出的结论是,只有在强制bash使用与Perl兼容的RegEx引擎时,我的问题才能解决。这可行吗?如果是这样,我将如何执行该程序?


5
您为什么不只使用perl而不是bash来编写脚本?为什么这个问题标记为javascript?
Marco Marco

因为在我的情况下必须使用Bash。而且我不小心标记了JavaScript。我将其删除了:)
Fadi Hanna AL-Kass 2013年

2
为什么不grep与一起-P使用sed
cuonglm

2
但是,您永远无法解释导致您得出结论,那就是您必须让shell执行它根本无法执行的操作的情况/问题。有更好的方法。
llua

我发现反向引用确实可以在bash 4.3.x(Ubuntu 14.04)中工作,但不能在bash 3.2x(OS X)中工作。这是我的测试命令:re="([a-z])[0-9]\1"; [[ a1a =~ $re ]] && echo ${BASH_REMATCH[0]}
Digital Trauma 2015年

Answers:


14

Bash目前不支持您执行此操作的方法。您剩下以下选项:

  1. 使用Perl
  2. 采用 grep [-P|--perl-regexp]
  3. 使用Bash功能对其进行编码

我想我会选择#2并尝试使用它grep来获得我想要的功能。对于反向引用,您可以使用以下方法grep

$ echo 'BEGIN `helloworld` END' | grep -oP '(?<=BEGIN `).*(?=` END)'
helloworld

-o, --only-matching       show only the part of a line matching PATTERN
-P, --perl-regexp         PATTERN is a Perl regular expression

(?=pattern)
    is a positive look-ahead assertion
(?!pattern)
    is a negative look-ahead assertion
(?<=pattern)
    is a positive look-behind assertion
(?<!pattern)
    is a negative look-behind assertion 

参考文献


老实说,我不知道grep有[-P|--perl-regexp]令牌。非常感谢:-)
法迪·汉娜·卡斯

@ FadiHannaAL-Kass-不用客气。谢谢你的问题。
slm

2
对于后代,只有GNU grep包含该-P选项,并且不是通用的。FreeBSD的grep基于GNU,但文档指出“ FreeBSD不支持该选项”。在OSX中,grep也是基于GNU的,但是-P手册页中甚至没有提到该选项。在其他grep不是GNU的unix系统上,您几乎看不到-P任何地方。如果您极有可能将来对您很有用,那么我建议您避免使用此类特定于操作系统的选项。
ghoti 2015年

pcregrep如果可用,也是一个选项。
2016年

应该注意的是,只要REMATCH_PCRE设置了该选项,zsh就会执行OP所要求的操作。
Tim Peoples

0

一个可以使用pcregrep。它随pcreCentOS和pcregrepUbuntu中的软件包一起提供。

grep -P 可能会出现此问题,具体取决于操作系统/版本:

-P, --perl-regexp
              Interpret PATTERN as a Perl regular expression.  This is highly experimental and grep -P may warn of unimplemented features.
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.