2010-01-23 8 views
9

Tôi đang cố gắng kiểm tra xem một biến là chính xác hai con số nhưng tôi dường như không thể tìm ra nó.Regex trong KornShell

Làm cách nào để kiểm tra cụm từ thông dụng (regex) trong KornShell (ksh)?

Tôi đã thử:

if [[ $month =~ "[0-9]{2}" ]] 
if [[ $month = _[0-9]{2}_ ]] 

tôi đã không thể tìm thấy bất kỳ tài liệu trên đó.

Bất kỳ thông tin chi tiết nào?

Trả lời

8
case $month in 
    [0-9][0-9]) echo "ok";; 
    *) echo "no";; 
esac 

sẽ hoạt động.

Nếu bạn cần tìm kiếm đầy đủ regexp, bạn có thể sử dụng egrep như thế này:

if echo $month | egrep -q '^[0-9]{2}$' 
then 
    echo "ok" 
else 
    echo "no" 
fi 
+0

Trong khi sử dụng egrep sẽ làm việc, nó là một chương trình bên ngoài và sẽ làm chậm kịch bản rất nhiều. – user1683793

0

bạn có thể thử này cũng

$ month=100 
$ [[ $month == {1,2}([0-9]) ]] && echo "ok" || echo "no" 
no 
$ [[ $month == [0-9][0-9] ]] && echo "ok" || echo "no" 
no 
$ month=10 
$ [[ $month == {1,2}([0-9]) ]] && echo "ok" || echo "no" 
ok 
$ [[ $month == [0-9][0-9] ]] && echo "ok" || echo "no" 
ok 
5

Nơi tôi đến từ đâu, đây là nhiều khả năng để xác nhận số tháng:

if (($month >= 1 && $month <= 12)) 

hoặc

[[ $month =~ ^([1-9]|1[012])$ ]] 

hoặc để bao gồm một số không hàng đầu trong nhiều tháng một con số:

[[ $month =~ ^(0[1-9]|1[012])$ ]] 
3

ksh không sử dụng biểu thức thông thường; nó sử dụng một ngôn ngữ đơn giản nhưng vẫn khá hữu ích được gọi là "mô hình vỏ quả cầu". Ý tưởng chính là

  • Các lớp như [0-9] hoặc [chly] khớp với bất kỳ ký tự nào trong lớp.
  • . không phải là ký tự đặc biệt; nó chỉ khớp với ..
  • ? khớp với bất kỳ ký tự đơn nào.
  • * khớp với bất kỳ chuỗi ký tự nào.
  • Không giống như cụm từ thông dụng, mẫu kết hợp vỏ phải khớp với toàn bộ từ, vì vậy nó hoạt động như thể nó là regexp, nó luôn bắt đầu bằng ^ và kết thúc bằng $.

Mẫu toàn cầu không mạnh bằng cụm từ thông dụng, nhưng dễ đọc hơn và rất thuận tiện cho việc khớp tên tệp và các từ đơn giản. Việc xây dựng case là yêu thích của tôi cho phù hợp nhưng có những người khác.

Như đã ghi nhận của Alok có thể bạn muốn

case $number in 
    [0-9][0-9]) success ;; 
    *) failure;; 
esac 

Mặc dù có thể bạn có thể không thích để phù hợp với một số có hai chữ số với ban đầu bằng không, vì vậy thích [1-9][0-9].

+2

ksh93 hỗ trợ cả biểu thức chính quy và mở rộng bằng cách sử dụng toán tử liên kết = ~ – cdarke

+1

+1 để giải thích sự khác biệt chính giữa các biểu thức và mẫu; @cdarke: đó là điều tốt để biết, nhưng tôi không thể làm cho nó hỗ trợ các biểu thức _interval_ như '{2}'; ví dụ. '[[11 = ~ [0-9] {2}]] && echo YES' gây ra lỗi cú pháp; '\' -xác định các dấu ngoặc kết quả không khớp; Tôi đang thiếu một cái gì đó ('ksh 93u')? – mklement0

7

ksh đã hỗ trợ mô hình mở rộng hạn chế kể từ ksh88, sử dụng cú pháp

special '(' pattern ')' 

.

Trong ksh88, các tiền tố nhân vật 'đặc biệt' thay đổi số lượng các trận đấu dự kiến:

'*' for zero or more matches 
'+' at least one match 
'@' for exactly one match 
'?' for zero or one matches 
'!' for negation 

Trong ksh93, điều này đã được mở rộng với

'{' min ',' max '}' 

đưa ra phạm vi chính xác:

for w in 1423 12 "" abc 23423 9 33 3 333 
do 
    [[ $w == {1,3}(\d) ]] && print $w has between 1 and three digits 
    [[ $w == {2}(\d) ]] && print $w has exactly two digits 
done 

Và cuối cùng, bạn có thể có sự lộn xộn giống như perl với '~', trong đó giới thiệu một hoàn toàn mới lớp các phần mở rộng, bao gồm các biểu đầy đủ thường xuyên với:

'~ (E) (regex)'

Thêm ví dụ có thể được tìm thấy trong Finnbarr P. Murphy's blog

+3

Bạn không cần ~ (E) nếu bạn sử dụng = ~, đó là mặc định – cdarke