Phân biệt chữ hoa chữ thường


10

Hãy xem xét kịch bản Bash này:

#!/bin/bash
echo Enter any character
read char
case $char in
    [a-z]) echo Lower case letter
            ;;
    [A-Z]) echo Upper case letter
            ;;
    [0-9]) echo Number
            ;;
    ?) echo Special char
            ;;
    *) echo You entered more than one character 
            ;;
esac

Nếu tôi nhập 'a', đầu ra là chữ thường và nó giống với 'A' ... Làm thế nào để tôi vượt qua điều này?


Khi bạn đăng một tập lệnh, đảm bảo bạn sử dụng định dạng mã, để giữ khoảng trắng. Ngoài ra, câu hỏi thực tế là gì? Tôi không chắc ý của bạn là gì ...
AJefferiss 13/03/2015

2
@Arronical không cần, echo có thể xử lý các từ dành riêng echo if case then do.
terdon

Đối với một vấn đề tương tự, nhưng đối phó với sắp xếp, hãy xem Askubfox.com/questions/597924/ Khăn
Joe

Câu trả lời:


20
#!/bin/bash
echo 'enter any character'
read char
case $char in
[[:lower:]]) echo 'lower case letter'
    ;;
[[:upper:]]) echo 'upper case letter'
    ;;
[0-9]) echo 'number'
    ;;
?) echo 'special char'
    ;;
*) echo 'u entered more than one char' 
    ;;
esac  

Để biết thêm thông tin về biểu thức chính quy viết thường của [az] và biểu thức chính quy của chữ [AZ] trong bash, hãy xem Tại sao câu lệnh không phân biệt chữ hoa chữ thường khi tắt nocasematch? .


6
Theo dõi từ điều này, thay vì [0-9]bạn có thể sử dụng [[:digit:]]. Bạn có thể tìm thấy nhiều ví dụ trong man grephoặc các lớp ký tự Google posix .
Paddy Landau

21

Vấn đề là phạm vi ký tự [a-z]thực sự bao gồm các chữ cái viết hoa. Điều này được giải thích trong hướng dẫn bash :

Trong một biểu thức ngoặc, một biểu thức phạm vi bao gồm hai ký tự được phân tách bằng dấu gạch nối. Nó phù hợp với bất kỳ nhân vật duy nhất sắp xếp giữa hai nhân vật, bao gồm. Trong ngôn ngữ C mặc định, trình tự sắp xếp là thứ tự ký tự gốc; ví dụ: '[quảng cáo]' tương đương với '[abcd]'. Ở các địa phương khác, trình tự sắp xếp không được chỉ định và '[quảng cáo]' có thể tương đương với '[abcd]' hoặc '[aBbCcDd]' hoặc có thể không khớp với bất kỳ ký tự nào hoặc tập hợp các ký tự mà nó Các trận đấu thậm chí có thể thất thường. Để có được cách hiểu truyền thống về biểu thức khung, bạn có thể sử dụng ngôn ngữ 'C' bằng cách đặt biến môi trường LC_ALL thành giá trị 'C'.

Để minh họa:

$ case B in [a-c]) echo YES;;  *) echo NO;; esac
YES
$ LC_ALL=C; case B in [a-c]) echo YES;; *) echo NO;; esac
NO

Vì vậy, những gì xảy ra là ở địa phương của bạn (mà không phải C), [a-c]thực sự là [aAbBcC]. Đó là lý do tại sao bạn nên sử dụng các lớp ký tự POSIX theo đề xuất của @karel.


4
Chính xác hơn, bạn cần phải đặt LC_COLLATEthành C, các cài đặt ngôn ngữ khác sẽ khác. Thiết lập LC_COLLATEbất cứ điều gì nhưng Chiếm khi là một ý tưởng tốt nhưng thật đáng buồn là Ubuntu thực hiện nó (nó không phải là thủ phạm duy nhất cho đến nay).
Gilles 'SO- ngừng trở nên xấu xa'
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.