2015-10-15 108 views
3

我做了这个正则表达式,但它不工作。bash为什么我的正则表达式不工作?

我得到这个字符串: ( '/test/test/test/test-Test/TEST/test.sql'),

我的bash代码:

if [[ ${arrayQuery[$i]} =~ ([a-z0-9]+)\/([a-z0-9]+)\/([a-z0-9]+)\/([a-z0-9-]+)\/([a-z0-9]+)\/([a-z0-9]+).([a-z0-9]+) ]]; then 
     queryName=$1 
     echo "test $queryName" 
fi 

它不是任何人都可以解释我为什么这不起作用?

我在regex101.com上试了我的正则表达式,正则表达式在本网站上工作。

+1

它看起来对我来说,你只是在寻找小写字母和数字,但你必须在本例中字符串大写字母,所以它不应该匹配。 –

+0

您不需要在正则表达式中转义'/'。 ''bash'不会像'sed'那样用它作为分隔符,例如',所以它们没有特殊的含义。 – chepner

+0

我可以问你,为什么你使用这个正则表达式?你是否试图将你的路径分成它的dir组件? –

回答

0

如果您将A-Z(大写字母)添加到所有字符集,它应该可以工作。

2
  • 你需要躲避点,否则匹配任何字符

  • 你的榜样字符串包含大写字母,但你的正则表达式只接受小写字母

(编辑:无报价需要)

0

您可以使用[[:alnum:]]作为(正确)类[a-zA-Z0-9]的捷径,以简化您的正则表达式,而fixi它。即使是简单的将是使用参数来缩短:

x='[[:alnum:]]+' 
# Or, if you prefer 
# x='[a-zA-Z0-9]+' 
if [[ ${arrayQuery[$i]} =~ ($x)/($x)/($x)/($x)/($x)/($x)\.($x) ]]; then 
    queryName=$1 
    echo "test $queryName" 
fi 

也有使正则表达式的选项匹配不区分大小写的,这样可以让你使用当前的正则表达式(有一些小的修正) :

shopt -s nocasematch 
if [[ ${arrayQuery[$i]} =~ ([a-z0-9]+)/([a-z0-9]+)/([a-z0-9]+)/([a-z0-9-]+)/([a-z0-9]+)/([a-z0-9]+)\.([a-z0-9]+) ]]; then 
    queryName=$1 
    echo "test $queryName" 
fi 
shopt -u nocasematch # Turn it off again 
+1

你错过了那个“ - ”字符,需要匹配“test-Test”部分 –

+1

好点。不知道这应该在每个组件中,还是只在包含用户输入中的组件中。目前还不清楚正则表达式应该是什么。 – chepner

+0

你还错过了字符串'/test/test/test/test-Test/TEST/test.sql'的第一个字符'/',因为你的正则表达式以“([a-z0-9] +)开始” –

1

您的例子并不在regex101与你有几个原因提供的字符串工作:

  1. 你的字符串以“/”开头,但您正则表达式用([A-Z0-9开始] +)
  2. 你的字符串包含大写字母,你却不使用[AZ]在您的正则表达式
  3. 你的字符串包含一个“ - ”但是你的正则表达式不分析它,尝试添加\ -
  4. 你没有逃脱该点用'\。'替换,默认为'。'。意味着所有的字符

这个正则表达式会做的伎俩(link to regex101):

\/[a-zA-Z0-9\-]+\/[a-zA-Z0-9\-]+\/[a-zA-Z0-9\-]+\/[a-zA-Z0-9\-]+\/[a-zA-Z0-9\-]+\/[a-zA-Z0-9\-]+\.[a-zA-Z0-9\-]+ 

我想这个字符串代表您的硬盘驱动器中的SQL文件,这个正则表达式可以简化为:

(\/[a-zA-Z0-9\-]+)+\.sql 

并且不依赖于目录树中有多少个文件夹。

+0

因此我将代码更改为:\t'code echo“$ {arrayQuery [$ i]}” \t if [[$ {arrayQuery [$ i]} =〜(\ /([a-zA-Z0-9 \ - ] +)\ /([A-ZA-Z0-9 \ - ] +)\ /([A-ZA-Z0-9 \ - ] +)\ /([A-ZA-Z0-9 \ - ] +)\ /([A-ZA-Z0-9 \ - ] +)\ /([A-ZA-Z0-9 \ - ] +)\([A-ZA-Z0-9 \ - ] + ))]]];然后 \t \t queryName = $ 1 \t \t回声“测试$ queryName” \t fi' – kaspertje100

+0

它不进入if语句现在(在控制台中我看到它打印测试),但它不打印$ queryName因为$ 1变量是空。我不明白为什么1美元是空的可以向我解释这一点吗? – kaspertje100

+0

Neverm ind修复它。我使用$ {BASH_REMATCH [1]}“来打印结果。在$ bash中不存在$ 1。 – kaspertje100

0

从您的评论看来,你似乎想将路径拆分成其组件。最好的选择,在Bash中,就是用这样的:

mypath=/testa/testb/testc/test-Testd/TESTe/test.sql 
IFS=/ read -r -d '' -a components < <(printf '%s\0' "$mypath") 

像这样,你就会有一个阵列components将包含路径的每个组件:

gniourf$ declare -p components 
declare -a components='([0]="" [1]="testa" [2]="testb" [3]="testc" [4]="test-Testd" [5]="TESTe" [6]="test.sql")' 

你不” t需要(并且不希望)为此使用正则表达式。

也看到了这个问题:How do I split a string on a delimiter in Bash?

相关问题