Trong một biểu thức chính quy, nhân vật nào cần thoát?


22

Nói chung, những nhân vật trong một biểu thức chính quy cần thoát?

Ví dụ, những điều sau đây không đúng về mặt cú pháp:

echo '[]' | grep '[]'
grep: Unmatched [ or [^

Điều này, tuy nhiên, đúng về mặt cú pháp:

echo '[]' | grep '\[]'
[]

Có tài liệu nào về các ký tự nên được thoát trong một biểu thức chính quy, và ký tự nào không nên?

Câu trả lời:


12

Điều này phụ thuộc vào ứng dụng. Trong ví dụ của bạn [phải được trích dẫn như một đối số cho grepnhưng không echo.

Đối với hệ vỏ (từ thông số kỹ thuật POSIX ):

Trích dẫn được sử dụng để loại bỏ ý nghĩa đặc biệt của các ký tự hoặc từ nhất định vào vỏ. Trích dẫn có thể được sử dụng để bảo tồn nghĩa đen của các ký tự đặc biệt trong đoạn tiếp theo, ngăn không cho các từ dành riêng được nhận ra như vậy và ngăn mở rộng tham số và thay thế lệnh trong xử lý tài liệu ở đây (xem Tài liệu ở đây).

Ứng dụng sẽ trích dẫn các ký tự sau nếu chúng đại diện cho chính chúng:

|  &  ;  <  >  (  )  $  `  \  "  '  <space>  <tab>  <newline>

và những điều sau đây có thể cần được trích dẫn trong những trường hợp nhất định. Đó là, các ký tự này có thể đặc biệt tùy thuộc vào các điều kiện được mô tả ở nơi khác trong tập này của IEEE Std 1003.1-2001:

*   ?   [   #   ˜   =   %

Các cơ chế trích dẫn khác nhau là ký tự thoát, dấu ngoặc đơn và dấu ngoặc kép. Tài liệu ở đây đại diện cho một hình thức trích dẫn khác; xem tài liệu ở đây

Các chương trình cụ thể (sử dụng regexes, perl, awk) có thể có các yêu cầu bổ sung về thoát.


8

Mỗi ứng dụng sẽ có bộ ký tự 'đặc biệt' riêng. Vấn đề mà bạn gặp grepphải không phải là cái vỏ. Đối với những ký tự nào cần được trích dẫn grep, hãy đọc phần của trang trên "GIẢI THÍCH THƯỜNG XUYÊN".

Đối với hệ vỏ, các ký tự cần được trích dẫn là:

;'"`#$&*?[]<>{}\

và bất kỳ khoảng trắng.

Tùy thuộc vào shell, các ký tự khác cũng có thể cần được trích dẫn:

!^%

Xem bên dưới "SHELL GRAMMAR" trên trang chủ của shell.


Trong một số shell có mở rộng lịch sử ( bashbao gồm), !vẫn được mở rộng trong dấu ngoặc kép, chỉ các dấu ngoặc đơn sẽ dừng việc mở rộng của nó (hoặc tắt tùy chọn shell).
Chris Xuống

]không nên được trích dẫn, [không phải luôn luôn. Tôi không tìm thấy bất kỳ tài liệu tham khảo nào {}
Matteo

8

Có nhiều loại biểu thức chính quy và tập hợp các ký tự đặc biệt phụ thuộc vào loại cụ thể. Một số trong số họ được mô tả dưới đây. Trong tất cả các trường hợp, các ký tự đặc biệt được thoát bằng dấu gạch chéo ngược \. Ví dụ để phù hợp với [bạn viết \[thay thế. Ngoài ra, các ký tự (ngoại trừ ^) có thể được thoát bằng cách đặt chúng giữa các dấu ngoặc vuông từng cái một [[].

Các ký tự đặc biệt trong một số ngữ cảnh như ^đặc biệt ở đầu biểu thức (phụ) có thể được thoát trong tất cả các ngữ cảnh.

Như những người khác đã viết: trong shell nếu bạn không bao gồm biểu thức giữa các trích dẫn đơn, bạn phải thoát thêm các ký tự đặc biệt cho shell trong regex đã thoát. Ví dụ: Thay vì '\['bạn có thể viết \\[(cách khác: "\["hoặc "\\[") trong các shell tương thích Bourne như bash nhưng đây là một câu chuyện khác.

Biểu thức chính quy cơ bản (BRE)

  • POSIX: Biểu thức chính quy cơ bản
  • Lệnh: grep,sed
  • Nhân vật đặc biệt: .[\
  • Đặc biệt trong một số bối cảnh: *^$
  • Thoát một chuỗi: "$(printf '%s' "$string" | sed 's/[.[\*^$]/\\&/g')"

Biểu thức chính quy mở rộng (ERE)

  • POSIX: Biểu thức chính quy mở rộng
  • Các lệnh : grep -E, GNU : sed -r, * BSD:sed -E
  • Nhân vật đặc biệt: .[\(
  • Đặc biệt trong một số bối cảnh: *^$)+?{|
  • Thoát một chuỗi: "$(printf '%s' "$string" | sed 's/[.[\*^$()+?{|]/\\&/g')"

3

grepsử dụng BRE làm phương thức regex của nó. Có tài liệu tốt về nó ở đây , một tóm tắt tổng quát sẽ là "thoát khỏi bất kỳ ký tự đặc biệt hoặc metacharater để có được nghĩa đen của nó, chạy trốn để tạo ra chuỗi thoát ( \n, \r, vv)", mặc dù điều này không phải lúc nào cũng đúng, ví dụ, bạn phải thoát ra ()để có được ý nghĩa đặc biệt của chúng (phản ứng ngược).


0

Shell có thể biến đổi dòng lệnh trước khi thực hiện lệnh. Cả vỏ và grepcó thể sử dụng trích dẫn để loại bỏ ý nghĩa đặc biệt của một số ký tự. Tuy nhiên, grepvà vỏ có các ký tự đặc biệt khác nhau. Ngoài ra, các ký tự đặc biệt không thoát khỏi kết quả của một bản mở rộng hiện có sẽ bị xóa, trước khi thực thi lệnh, bằng shell.

echo '[]' | grep '[]'

Shell truyền đối số []tới grepvà nó được phân tích cú pháp dưới dạng biểu thức ngoặc không đúng grep.

echo '[]' | grep \[]

Ở trên, chúng ta có thể thấy một trường hợp tương tự. Dấu gạch chéo ngược được loại bỏ và []được truyền dưới dạng đối số grep. grepnhận ra một biểu thức khung không đúng.

echo '[]' | grep '\[]'

Cuối cùng, trong trường hợp này, các trích dẫn được loại bỏ bởi shell và \[]được truyền dưới dạng đối số đến grep, nhưng trong trường hợp cụ thể này, \[được hiểu greplà một dấu ngoặc. Các trích dẫn là cần thiết để ngăn chặn việc giải thích dấu gạch chéo ngược như là một ký tự đặc biệt của trình bao.


Specification Đặc điểm kỹ thuật POSIX .

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.