2016-01-07 20 views
9

Lưu ý rằng đây là không một bản sao của nhiều câu hỏi về StackOverflow liên quan gcc, Tôi đang sử dụng Visual Studio 2013.std :: regex constructor ném một ngoại lệ

này xây dựng đơn giản của một biểu thức chính quy ném std::regex_error :

bool caseInsensitive = true; 
char pattern[] = "\\bword\\b"; 
std::regex re(pattern, std::regex_constants::ECMAScript | (caseInsensitive ? std::regex_constants::icase : 0)); 

Lỗi thực tế được trả về bởi what trên đối tượng ngoại lệ không nhất quán. Thông thường nó là một parethesis không khớp hoặc cú đúp. Tại sao?

Trả lời

11

Sự cố phát sinh do nhiều nhà thầu có sẵn cho std::regex. Truy tìm vào các nhà xây dựng cho thấy nó bằng cách sử dụng một trong tôi đã không có ý định!

Tôi muốn sử dụng cái này:

explicit basic_regex(_In_z_ const _Elem *_Ptr, 
    flag_type _Flags = regex_constants::ECMAScript) 

Nhưng tôi có một này để thay thế:

basic_regex(_In_reads_(_Count) const _Elem *_Ptr, size_t _Count, 
    flag_type _Flags = regex_constants::ECMAScript) 

Khái niệm ternary trong những lá cờ gây ra các loại để thay đổi int, trận đấu mà không còn flag_type trong chữ ký hàm tạo. Vì nó hiện kết hợp trên size_t nó gọi hàm tạo đó thay thế. Các cờ được hiểu sai là kích thước của chuỗi, dẫn đến hành vi không xác định khi bộ nhớ vượt qua cuối chuỗi được truy cập.

Sự cố không dành riêng cho Visual Studio. Tôi đã có thể sao chép nó trong gcc: http://ideone.com/5DjYiz

Có thể sửa hai cách. Đầu tiên là một diễn viên rõ ràng của đối số:

std::regex re(pattern, static_cast<std::regex::flag_type>(std::regex_constants::ECMAScript | (caseInsensitive ? std::regex_constants::icase : 0))); 

Thứ hai là để tránh các hằng số nguyên trong biểu thức ternary:

std::regex re(pattern, caseInsensitive ? std::regex_constants::ECMAScript | std::regex_constants::icase : std::regex_constants::ECMAScript); 
6

Tôi không tìm thấy một trong các giải pháp được đề nghị đặc biệt hấp dẫn hoặc thẩm mỹ. Tôi nghĩ rằng tôi muốn một cái gì đó như thế này:

auto options = std::regex_constants::ECMAScript; 
if (caseInsensitive) 
    options |= std::regex_constants::icase; 

std::regex re(pattern, options); 

Nếu vì một lý do sai lầm, bạn thực sự nhấn mạnh vào một dòng mã, tôi muốn sử dụng một đối tượng giá trị xây dựng của các loại chính xác trong ternary biểu hiện:

std::regex re(pattern, std::regex_constants::ECMAScript | (caseInsensitive ? std::regex_constants::icase : std::regex_constants::std::regex_option_type{})); 

Hoặc, vì ECMAScript là mặc định, bạn sử dụng:

std::regex re(pattern, (caseInsensitive ? std::regex_constants::icase : std::regex_constants::ECMAScript)); 

ít nhất đến mắt của tôi, là người đầu tiên trong số này là rõ ràng thích hợp mặc dù.

+0

Giải pháp của bạn chắc chắn dễ đọc hơn, cảm ơn. –

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