grep caret dường như không có tác dụng


7

Tôi có ấn tượng rằng một biểu tượng dấu mũ có nghĩa là " bắt đầu của dòng " với các biểu thức chính quy POSIX mở rộng.

Tuy nhiên, khi tôi sử dụng nó với grepnó cư xử bất ngờ.

Tôi đang sử dụng GNU grep 2.5.4 trên Ubuntu 10.04 Lucid Lynx .

Tôi lặp lại một dòng ' xin chào ', sau đó chuyển nó thành một dòng greptìm kiếm " các ký tự khoảng trắng bằng không hoặc nhiều hơn theo sau là chữ h ":

echo ' hello' | grep -E '[:space:]*h'
hello

grep thấy nó ổn

Nếu tôi thêm một dấu mũ để chỉ ra rằng tôi chỉ muốn mẫu khớp với " các ký tự khoảng trắng bằng 0 hoặc nhiều hơn theo sau là chữ h ở đầu chuỗi ":

echo ' hello' | grep -E '^[:space:]*h'

Không có trận đấu được tìm thấy. Tôi hy vọng chuỗi đã khớp bởi vì nó bắt đầu bằng khoảng trắng theo sau là h .

Tại sao biểu tượng dấu mũ này ngăn cản một trận đấu?

Câu trả lời:


7

Để tìm một khoảng trắng, bạn phải sử dụng [:space:]bên trong một cặp dấu ngoặc khác, nó sẽ trông như thế [[:space:]]. Bạn có thể có nghĩa là để thể hiệngrep -E '^[[:space:]]*h'

Để giải thích tại sao cái hiện tại của bạn thất bại:

Khi đứng, [:space:]*hbao gồm một lớp nhân vật tìm kiếm bất kỳ ký tự: :, s, p, a, c, và exảy ra bất kỳ số lần (bao gồm 0), tiếp theo h. Điều này phù hợp với chuỗi của bạn, nhưng nếu bạn chạy grep -o, bạn sẽ thấy rằng bạn chỉ khớp với h, không phải không gian.

Nếu bạn thêm một carat vào đầu, một trong những chữ cái đó hoặc hphải ở đầu chuỗi để khớp, nhưng không có gì, vì vậy nó không khớp.


Aaahaa. Điều này thật ý nghĩa.
JW01

4

Có vẻ như nó giả định rằng [:space:]sẽ chỉ xuất hiện trong một biểu thức ngoặc (được tô sáng khớp với *):

echo 'hello' | grep -E '^[:space:]*h'
*h*ello
echo 'hello' | grep -E '[^[:space:]]*h'
*h*ello
echo ' hello' | grep -E '^[[:space:]]*h'
* h*ello

Điều này được giải thích bởi đoạn trích sau từ man grep(phần tô sáng của tôi):

Cuối cùng, một số lớp ký tự được đặt tên nhất định được xác định trước trong biểu thức ngoặc vuông [...] Lưu ý rằng dấu ngoặc trong các tên lớp này là một phần của tên biểu tượng và phải được thêm vào cùng với dấu ngoặc phân cách biểu thức ngoặc.


Đúng. Tôi nghĩ đó là chính xác. Tôi vừa nhận thấy người đàn ông "(Lưu ý rằng dấu ngoặc trong các tên lớp [được xác định trước] này là một phần của tên tượng trưng và phải được thêm vào cùng với dấu ngoặc phân cách biểu thức ngoặc.)"
JW01
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.