#!/bin/bash
INT=-5
if [[ "$INT" =~ ^-?[0-9]+$ ]]; then
echo "INT is an integer."
else
echo "INT is not an integer." >&2
exit 1
fi
Những gì hàng đầu ~
làm trong biểu thức thường xuyên bắt đầu?
#!/bin/bash
INT=-5
if [[ "$INT" =~ ^-?[0-9]+$ ]]; then
echo "INT is an integer."
else
echo "INT is not an integer." >&2
exit 1
fi
Những gì hàng đầu ~
làm trong biểu thức thường xuyên bắt đầu?
Câu trả lời:
Đây ~
thực sự là một phần của toán tử =~
thực hiện khớp biểu thức chính quy của chuỗi bên trái với biểu thức chính quy mở rộng ở bên phải.
[[ "string" =~ pattern ]]
Lưu ý rằng chuỗi nên được trích dẫn và biểu thức chính quy không nên được trích dẫn.
Một toán tử tương tự được sử dụng trong ngôn ngữ lập trình Perl.
Các biểu thức chính quy được hiểu bash
giống như các biểu thức mà GNU grep
hiểu với -E
cờ, tức là tập hợp các biểu thức chính quy mở rộng.
Hơi lạc đề, nhưng nên biết:
Khi khớp với biểu thức chính quy có chứa các nhóm bắt giữ, một phần của chuỗi được bắt bởi mỗi nhóm có sẵn trong BASH_REMATCH
mảng. Các 0 / nhập đầu tiên trong mảng này tương ứng với &
trong mô hình thay thế sed
của lệnh thay thế (hoặc $&
trong Perl), đó là các bit của chuỗi phù hợp với mô hình, trong khi các mục ở chỉ số 1 và trở đi tương ứng với \1
, \2
, vv . trong một sed
mẫu thay thế (hoặc $1
, $2
v.v. trong Perl), tức là các bit khớp với từng dấu ngoặc đơn.
Thí dụ:
string=$( date +%T )
if [[ "$string" =~ ^([0-9][0-9]):([0-9][0-9]):([0-9][0-9])$ ]]; then
printf 'Got %s, %s and %s\n' \
"${BASH_REMATCH[1]}" "${BASH_REMATCH[2]}" "${BASH_REMATCH[3]}"
fi
Điều này có thể đầu ra
Got 09, 19 and 14
nếu thời điểm hiện tại xảy ra là 09:19:14.
Các REMATCH
bit của BASH_REMATCH
tên mảng xuất phát từ "Regular Expression trận đấu", tức là "RE-Match".
Trong các bash
shell không giống Bourne, người ta cũng có thể sử dụng expr
cho kết hợp biểu thức chính quy giới hạn (chỉ sử dụng các biểu thức chính quy cơ bản).
Một ví dụ nhỏ:
$ string="hello 123 world"
$ expr "$string" : ".*[^0-9]\([0-9][0-9]*\)"
123
grep -E
chỉ hiểu trên các hệ thống GNU và chỉ khi sử dụng một biến không được trích dẫn làm mẫu [[ $var = $pattern ]]
(xem [[ 'a b' =~ a\sb ]]
so với p='a\sb'; [[ 'a b' =~ $p ]]
). Ngoài ra, hãy cẩn thận khi trích dẫn shell ảnh hưởng đến ý nghĩa của các toán tử RE và một số ký tự cần được trích dẫn cho mã thông báo shell có thể ảnh hưởng đến quá trình xử lý RE. [[ '\' =~ [\/] ]]
trả về sai. ksh93
thậm chí còn có vấn đề tồi tệ hơn Xem zsh
(hoặc bash 3.1) để biết cách tiếp cận saner trong đó trích dẫn shell và RE được phân tách rõ ràng. Nội dung [
của zsh
và yash
cũng có một =~
toán tử.
off-topic
! +1 (
[[ "This is a fine mess." =~ T.........fin*es* ]]; [[ "This is a fine mess." =~ T.........fin\*es\* ]]
. Hoặc là một trích dẫn *
cũng phù hợp? [[ "This is a fine mess." =~ "T.........fin*es*" ]]
.
[[ a =~ .* ]]
hoặc [[ a =~ '.*' ]]
hoặc [[ a =~ \.\* ]]
, cùng một .*
RE được truyền cho =~
toán tử. OTH, trong bash
, [[ '\' =~ [)] ]]
trả về một lỗi, bạn có biết mà không thử xem nó có [[ '\' =~ [\)] ]]
khớp không? Làm thế nào về [[ '\' =~ [\/] ]]
(nó làm trong ksh93). Làm thế nào về c='a-z'; [[ a =~ ["$c"] ]]
(so sánh với các =
nhà điều hành)? Xem thêm: [[ '\' =~ [^]"."] ]]
đó trả về false ... Lưu ý rằng bạn có thể làm shopt -s compat31
trong bash
để có được zsh
hành vi.
zsh
bash -o compat31
Hành vi của / [[ a =~ '.*' ]]
cũng phù hợp với [ a '=~' '.*' ]
(đối với [
việc triển khai hỗ trợ =~
) hoặc expr a : '.*'
. OTOH, nó không phù hợp với [[ a = '*' ]]
vs [[ a = * ]]
(nhưng sau đó, các khối là một phần của ngôn ngữ shell, trong khi RE thì không).
Bạn nên đọc các trang bash man, dưới [[ expression ]]
phần.
An additional binary operator, =~, is available, with the same precedence as == and !=. When it is used, the string to the right of the operator is considered an extended regular expression and matched accordingly (as in regex(3)).
Câu chuyện dài, =~
là một nhà điều hành, giống như ==
và !=
. Nó không có gì để làm với regex thực tế trong chuỗi bên phải của nó.
=~
trong cuộc sống thực ...?
man [[ expresssion ]]
và man [[
lợi nhuận gì cả. help [[
trả về thông tin hữu ích, kể từ [[
lệnh bash nội bộ, nhưng không cho biết =~
sử dụng cú pháp regex cơ bản hay mở rộng. Văn bản bạn trích dẫn là từ trang bash man. Tôi nhận ra bạn đã nói rằng người đọc các trang bash man, nhưng lúc đầu, tôi nghĩ bạn có nghĩa là đọc các trang của người đàn ông trong bash. Ở bất kỳ giá nào, man bash
trả về một tệp khổng lồ, dài 4139 dòng (72 trang). Nó có thể được tìm kiếm bằng cách nhấn /▒▒▒
, trong đó có một biểu thức chính quy, hương vị mà tinh thần giống =~
nhưisis không được chỉ định.