Cờ DOTALL
cho phép người .
newlines trận đấu, nhưng nếu bạn chỉ đơn giản là áp dụng nó vào regex hiện tại của bạn, bạn sẽ kết thúc phù hợp với mọi thứ từ CREATE
đầu tiên đến ;
cuối cùng trong một lần. Nếu bạn muốn kết hợp các câu lệnh riêng lẻ, bạn sẽ cần phải làm nhiều hơn. Một lựa chọn là sử dụng một lượng hóa phi tham lam:
Pattern p = Pattern.compile("^CREATE\\b.+?;",
Pattern.DOTALL | Pattern.MULTILINE | Pattern.CASE_INSENSITIVE);
Tôi cũng sử dụng MULTILINE
cờ để cho các trận đấu ^
neo sau dòng mới, và CASE_INSENSITIVE
vì SQL được - ít nhất, mỗi hương vị tôi đã nghe nói về . Lưu ý rằng cả ba lá cờ có "inline" hình thức mà bạn có thể sử dụng trong regex bản thân:
Pattern p = Pattern.compile("(?smi)^CREATE\\b.+?;");
(Hình thức inline của DOTALL
là s
vì những lý do lịch sử, nó được gọi là "single-line" chế độ trong Perl, . nơi nó có nguồn gốc) một lựa chọn khác là sử dụng một lớp nhân vật phủ nhận:
Pattern p = Pattern.compile("(?mi)^CREATE\\b[^;]+;");
[^;]+
trận đấu một hoặc nhiều của bất kỳ nhân vật ngoại trừ ;
--that bao gồm dòng mới, vì vậy cờ s
là không cần thiết.
Cho đến giờ, tôi đã giả định rằng mọi câu lệnh đều bắt đầu ở đầu dòng và kết thúc bằng dấu chấm phẩy, như trong ví dụ của bạn. Tôi không nghĩ rằng một trong những điều đó là bắt buộc bởi các tiêu chuẩn SQL, nhưng tôi hy vọng bạn sẽ biết nếu bạn có thể đếm trên chúng trong trường hợp này.Bạn có thể muốn bắt đầu phù hợp tại một ranh giới từ thay vì một ranh giới dòng:
Pattern p = Pattern.compile("(?i)\\bCREATE\\b[^;]+;");
Cuối cùng, nếu bạn đang suy nghĩ về bất cứ điều gì làm phức tạp hơn với regexes và SQL, không. Phân tích cú pháp SQL với regexes là trò chơi của kẻ ngốc - nó thậm chí còn tệ hơn cả HTML và regex.