2011-07-12 31 views
5

Tại sao tập lệnh bash sau chỉ in ra variable worked?Tại sao không thể sử dụng các chuỗi ký tự trong các phép thử biểu thức chính quy?

#! /bin/bash 

foo=baaz 
regex='ba{2}z' 

if [[ $foo =~ 'ba{2}z' ]]; then 
    echo "literal worked" 
fi 

if [[ $foo =~ $regex ]]; then 
    echo "variable worked" 
fi 

Có điều gì trong tài liệu bash nêu rõ toán tử =~ chỉ hoạt động với các biến, không phải chữ? Giới hạn này có áp dụng cho bất kỳ nhà khai thác nào khác không?

+0

Trong trường hợp có liên quan, tôi đang chạy 'GNU bash, phiên bản 4.2.8 (1) -release (x86_64-pc-linux-gnu)' trên Natty Narwhal. – splicer

Trả lời

7

Bạn không cần dấu ngoặc kép cho bash regex nữa:

#! /bin/bash 

foo=baaz 
regex='ba{2}z' 

if [[ $foo =~ ba{2}z ]]; then 
    echo "literal worked" 
fi 

if [[ $foo =~ $regex ]]; then 
    echo "variable worked" 
fi 

# Should output literal worked, then variable worked 

Tôi không thể nhớ được phiên bản thay đổi này mặc dù.

1

Mã của bạn thực sự hoạt động như mong đợi cho đến khi Bash 3.1. Nhưng kể từ Bash 3.2, hành vi của toán tử đối sánh mẫu đã được thay đổi. Trích dẫn từ mới nhất Bash Manual:

“Bất kỳ một phần của mô hình có thể được trích dẫn để buộc nó để được xuất hiện như là một chuỗi .”

Và đó là chính xác những gì đang xảy ra ở đây. Bạn có nghĩa là sử dụng {} làm ký tự meta, nhưng kể từ khi bạn trích dẫn nó Bash diễn giải chúng theo nghĩa đen. Bạn có hai lựa chọn .:

1.You có thể bật chế độ 3.1 tương thích với shopt -s compat31 như thế này:

#!/bin/bash 
shopt -s compat31 

foo=baaz 
regex='ba{2}z' 

if [[ $foo =~ 'ba{2}z' ]]; then 
    echo "literal worked" 
fi 

if [[ $foo =~ $regex ]]; then 
    echo "variable worked" 
fi 

2.You có thể cổng mã của bạn, bằng cách loại bỏ những trích dẫn từ phía bên tay phải của nhà điều hành:

#!/bin/bash 

foo=baaz 
regex='ba{2}z' 

if [[ $foo =~ ba{2}z ]]; then 
    echo "literal worked" 
fi 

if [[ $foo =~ $regex ]]; then 
    echo "variable worked" 
fi 
Các vấn đề liên quan