2014-05-06 15 views
8

LƯU Ý: Khi tôi nói regex [\0] Ý tôi là regex [\0] (không chứa trong một chuỗi C-phong cách, mà sau đó sẽ là "[\\0]"). Nếu tôi không đặt dấu ngoặc kép xung quanh nó, nó không phải là một chuỗi kiểu C, và các dấu gạch chéo ngược không nên được hiểu là thoát khỏi một chuỗi kiểu C.Có 0 ("\ 0" trong chuỗi regex kiểu C) một chuỗi thoát hợp lệ trong biểu thức chính quy C++ không?

Lấy cảm hứng từ this question and my investigation, tôi đã thử đoạn mã sau vào kêu vang 3.4:

#include <regex> 
#include <string> 

int main() 
{ 
    std::string input = "foobar"; 
    std::regex regex("[^\\0]*"); // Note, this is "\\0", not "\0"! 

    return std::regex_match(input, regex); 
} 

Rõ ràng, kêu vang không thích điều này, vì nó ném:

std::__1::regex_error: Biểu thức chứa một hợp lệ ký tự thoát, hoặc một lối thoát.

Có vẻ như là phần [^\0] (thay đổi thành [^\n] hoặc điều gì đó tương tự hoạt động tốt). Nó có vẻ là một nhân vật thoát không hợp lệ. Tôi muốn làm rõ rằng tôi không nói về ký tự '\0' (ký tự null) hoặc ký tự '\n' (ký tự dòng mới). Trong chuỗi kiểu C, nội dung tôi đang nói đến là "\\0" (chuỗi có chứa dấu gạch chéo ngược 0) "\\n" (chuỗi chứa dấu gạch chéo ngược n). "\\n" dường như được chuyển đổi thành "\n" bởi động cơ regex, nhưng nó bị nghẹt thở trên "\\0".

C++ 11 tiêu chuẩn nói trong phần 28.13 [re.grammar] rằng:

Ngữ pháp biểu thức chính quy được công nhận bởi basic_regex đối tượng được xây dựng với cờ ECMAScript được rằng theo quy định của ECMA-262, trừ khi được chỉ định bên dưới.

Tôi không có chuyên gia về ECMA-262, nhưng I tried the regular expression on JSFiddle và nó hoạt động tốt ở vùng đất JavaScript.

Vì vậy, bây giờ tôi tự hỏi nếu regex [^\0] là hợp lệ trong ECMA-262 và tiêu chuẩn C++ 11 loại bỏ hỗ trợ cho nó (trong các công cụ sau ... except as specified below.).

Câu hỏi: Liệu sản phẩm \0 (không null ký tự, trong một chuỗi chữ này sẽ "\\0") dãy thoát pháp lý trong một biểu thức chính quy C++ 11? Nó có hợp pháp trong ECMA-262 (hay là các máy ảo JS trình duyệt chỉ là "quá" khoan dung)? Nguyên nhân/biện minh cho các hành vi khác nhau là gì?

+0

http://stackoverflow.com/questions/15194513/how-can-i-match-the-0-character-in-a-regex-in-c – user3590396

+0

@ user3590396: Chắc chắn, tôi chỉ có thể viết '" [^ "+ std :: string (1, '\ 0') +"] * "' và được thực hiện với nó, nhưng tôi không hỏi * làm thế nào * để phù hợp với điều này, tôi hỏi * tại sao * có một sự khác biệt, với điều kiện là C++ 11 regexes dựa trên các regex của ECMA. – Cornstalks

+0

Tôi nghĩ rằng đó là bởi vì ECMA regexes sử dụng thứ tự chuỗi cao hơn và sẽ thoát \ 0 khi nó được nhập vào chuỗi thay vì biên dịch thành ký tự kết thúc chuỗi, trong khi chuỗi c kết thúc chuỗi, đó là lý do bạn cần để làm một số legwork để nội suy nó. –

Trả lời

2

Đây là lỗi trong việc triển khai libC++ <regex>. Nó phải được cố định ngay bây giờ trong thân cây, và điều này sẽ tuyên truyền cho mã phát hành OS X cuối cùng.

Ngoài ra, đây là đoạn trích từ ECMA 262 tiêu chuẩn đó là cơ sở để báo cáo lỗi này:

15.10.2.11 DecimalEscape

Việc sản xuất DecimalEscape :: DecimalIntegerLiteral [lookahead ∉ DecimalDigit] đánh giá như sau:

  1. Để tôi trở thành MV của DecimalIntegerLiteral.
  2. Nếu tôi bằng không, hãy trả về EscapeValue bao gồm một ký tự <NUL> (giá trị Unicode 0000).
  3. Trả về giá trị EscapeValue bao gồm số nguyên i.

Lưu ý: ... \ 0 đại diện cho < Ký tự NUL > và không thể theo sau bằng chữ số thập phân.

Các vấn đề liên quan