Ký tự meta Java RegEx (.) Và dấu chấm thông thường?


150

Trong Java RegEx, làm thế nào để tìm ra sự khác biệt giữa .(dấu chấm) ký tự meta và dấu chấm bình thường như chúng ta sử dụng trong bất kỳ câu nào. Làm thế nào để xử lý tình huống này cho các ký tự meta khác nữa như ( *, +, \d, ...)

Câu trả lời:


276

Nếu bạn muốn dấu chấm hoặc các ký tự khác có ý nghĩa đặc biệt trong biểu thức chính là một ký tự bình thường, bạn phải thoát nó bằng dấu gạch chéo ngược. Vì các biểu thức chính trong Java là các chuỗi Java bình thường, bạn cần thoát khỏi dấu gạch chéo ngược, do đó bạn cần hai dấu gạch chéo ngược, vd\\.


1
sửa lỗi này cũng áp dụng cho bash
krivar

18
Xin lưu ý rằng việc thoát khỏi dấu gạch chéo ngược phụ thuộc vào cách bạn cung cấp biểu thức chính quy. nếu mã hóa cứng, bạn cần sử dụng: "\\." , nếu đọc từ một nguồn thô (ví dụ: tệp văn bản), bạn chỉ sử dụng một dấu gạch chéo ngược duy nhất: \.
Paul

25

Các giải pháp được đề xuất bởi các thành viên khác không làm việc cho tôi.

Nhưng tôi đã tìm thấy điều này:

để thoát một dấu chấm trong java regrec write [.]


2
Tương tự, \\.không làm việc cho tôi: \.phàn nàn rằng .không cần phải trốn thoát, \\.khiến nó nghĩ rằng đó là \.thay vì ., \\\.và người xây dựng đã đưa ra một lỗi, [.]là điều duy nhất hoạt động.
mithunc

1
@mithunc Thật kỳ lạ, \\.bên trong một chuỗi ký tự cung cấp cho bạn \.đó là những gì regex cần để xem dấu chấm là một dấu chấm theo nghĩa đen thay vì trình so khớp bất kỳ ký tự nào.
klaar

16

Các biểu thức chính quy theo kiểu Perl (mà công cụ regex Java dựa trên ít nhiều) coi các ký tự sau là các ký tự đặc biệt:

.^$|*+?()[{\có ý nghĩa đặc biệt bên ngoài các lớp nhân vật,

]^-\có ý nghĩa đặc biệt bên trong các lớp nhân vật ( [...]).

Vì vậy, bạn cần phải thoát các biểu tượng đó (và chỉ những biểu tượng đó) tùy thuộc vào ngữ cảnh (hoặc, trong trường hợp các lớp nhân vật, đặt chúng vào các vị trí mà chúng không thể bị hiểu sai).

Không cần thoát các ký tự khác có thể hoạt động, nhưng một số công cụ regex sẽ coi đây là lỗi cú pháp, ví dụ \_sẽ gây ra lỗi trong .NET.

Một số người khác sẽ dẫn đến kết quả sai, ví dụ \<được hiểu là một nghĩa đen <trong Perl, nhưng trong egrepđó có nghĩa là "ranh giới từ".

Vì vậy, viết -?\d+\.\d+\$cho phù hợp 1.50$, -2.00$vv và [(){}[\]]cho một lớp nhân vật phù hợp với tất cả các loại dấu ngoặc / dấu ngoặc / dấu ngoặc đơn.

Nếu bạn cần chuyển đổi chuỗi đầu vào của người dùng thành dạng an toàn regex, hãy sử dụng java.util.regex.Pattern.quote.

Đọc thêm: RegexGuru của Jan Goyvaert về việc thoát khỏi các siêu nhân vật


4

Thoát khỏi các ký tự đặc biệt với dấu gạch chéo ngược. \., \*, \+, \\d, Và vân vân. Nếu bạn không chắc chắn, bạn có thể thoát khỏi bất kỳ ký tự không phải chữ cái nào cho dù nó đặc biệt hay không. Xem javadoc cho java.util.regex.Potype để biết thêm thông tin.


Thoát khỏi các ký tự không đặc biệt không cần thiết có thể hoạt động ở một số ngôn ngữ nhưng có thể thất bại ở các ngôn ngữ khác, vì vậy tốt hơn hết là đừng tập thói quen này.
Tim Pietzcker

1
Câu hỏi này đặc biệt về Java, và docs.oracle.com/javase/6/docs/api/java/util/regex/ cảm nói "Dấu gạch chéo ngược có thể được sử dụng trước ký tự không phải là chữ cái cho dù ký tự đó có phải là ký tự không một phần của công trình không được giải thoát. "
Christoffer Hammarström

2

Đây là mã bạn có thể sao chép trực tiếp dán:

String imageName = "picture1.jpg";
String [] imageNameArray = imageName.split("\\.");
for(int i =0; i< imageNameArray.length ; i++)
{
   system.out.println(imageNameArray[i]);
}

Và điều gì xảy ra nếu nhầm lẫn là có khoảng trống còn lại trước hoặc sau "." trong trường hợp này? Luôn luôn thực hành tốt nhất để xem xét những không gian đó.

String imageName = "picture1  . jpg";
String [] imageNameArray = imageName.split("\\s*.\\s*");
    for(int i =0; i< imageNameArray.length ; i++)
    {
       system.out.println(imageNameArray[i]);
    }

Ở đây, \ s * ở đó để xem xét các khoảng trắng và chỉ cung cấp cho bạn các chuỗi được tách yêu cầu.


1

Tôi muốn khớp chuỗi kết thúc bằng ". *" Vì điều này tôi phải sử dụng như sau:

"^.*\\.\\*$"

Thật là ngớ ngẩn nếu bạn nghĩ về nó: D Đây là ý nghĩa của nó. Ở đầu chuỗi có thể có bất kỳ ký tự nào 0 hoặc nhiều lần theo sau là dấu chấm "." theo sau là một ngôi sao (*) ở cuối chuỗi.

Tôi hy vọng điều này có ích cho một ai đó. Cảm ơn về điều ngược lại với Fabian.


Chỉ cần sử dụng "\\.\\*$"sau đó. Không cần phải khớp với phần đầu của chuỗi nếu nó không quan trọng với bạn.
Ophidian

Ư, bạn đung. Thành thật mà nói, tôi không thể nhớ lại trường hợp sử dụng cho việc này: /
Atspulgs

Không thực sự giúp bạn mà là giúp người khác nhìn vào bài đăng của bạn: P
Ophidian

0

Nếu bạn muốn kết thúc kiểm tra xem câu của bạn có kết thúc bằng ". " Thì bạn phải thêm [\. \ ] $ Vào cuối mẫu.


0

Tôi đang thực hiện một số mảng cơ bản trong JGrasp và thấy rằng với một phương thức truy cập cho một mảng char [] [] để sử dụng ('.') Để đặt một dấu chấm duy nhất.

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.