2011-10-21 37 views
5

Viết một regex đơn giản, nhưng tôi chưa bao giờ giỏi về điều này.Java Regex a-z, A-Z, 0-9 và (.) (_) (-)

Điều tôi đang cố gắng làm là kiểm tra chuỗi (tên tệp) để đảm bảo chỉ chứa ký tự a-z, A-Z, 0-9 hoặc ký tự đặc biệt (_) hoặc dấu gạch ngang (-).

Dưới đây là những gì tôi có

if(filename.length() < 1 || !filename.matches("^[a-zA-Z0-9[.][_][-]]+")) 
    return false; 
else 
    return true; 

này xuất hiện để làm việc, nhưng không trông rất thanh lịch với tôi. Có cách nào tốt hơn/dễ đọc hơn để viết cái này không?

Cảm ơn trước! Chỉ cần cố gắng tìm hiểu cách viết những trình điều khiển này tốt hơn.

-sẽ

+1

Những người khác đã trả lời câu hỏi regex, nhưng tôi tò mò tại sao bạn kiểm tra độ dài của chuỗi lớn hơn 1. Nếu chuỗi là "", nó không thể khớp '" ^. + "' – kojiro

+0

Điểm tốt. Nó còn sót lại từ một lần thực hiện trước đó. Cảm ơn! –

Trả lời

10

Bạn không cần sử dụng [] bên trong lớp ký tự.

Vì vậy, bạn có thể viết:

^[-a-zA-Z0-9._]+ 

Ngoài ra, bạn có thể sử dụng \\w thay vì a-zA-Z0-9_.

Vì vậy, regexp sẽ là:

^[-\\w.]+ 

Ngoài ra, regexp này sẽ phù hợp với một chuỗi như StackOverflow 22.10$$2011 bằng cách tiêu thụ StackOverflow 22.10. Nếu bạn cần chuỗi của bạn để bao gồm hoàn toàn của những nhân vật, bạn nên kết thúc mô hình với $ - sự kết thúc của chuỗi:

^[-\\w.]+$ 
+0

Trong thực tế, trong hầu hết các hương vị regex những dấu ngoặc vuông thêm sẽ được coi là một lỗi cú pháp. –

+0

Cảm ơn! Điều này có vẻ tốt hơn nhiều –

+0

Sử dụng \\ w sẽ cho phép bất kỳ ký tự UTF-8 nào, không chỉ là a-z và A-Z. Cũng lưu ý rằng. khớp với bất kỳ ký tự nào và cần phải được thoát nếu bạn ngụ ý chữ '.' –

1
try { 
    boolean foundMatch = subjectString.matches("^[\\w.-]+$"); 
} catch (PatternSyntaxException ex) { 
    // Syntax error in the regular expression 
} 

Hãy thử điều này.

Về cơ bản \ w là viết tắt của [a-zA-Z_0-9] và tôi chỉ cần thêm hai ký tự khác mà bạn muốn.

+0

Tôi không biết động cơ RE của Java, nhưng thông thường bạn cần phải neo vào đầu chuỗi, nếu không "@ # $% @ # $% foo" sẽ được chấp nhận. –

+0

@OscarKorz Đã thêm các neo trước khi tôi nhìn thấy chú thích m8 :) – FailedDev

+0

Phương thức 'matches()' của Java tự động neo đối sánh ở cả hai đầu, nhưng không có hại gì khi sử dụng các neo rõ ràng, và tôi nghĩ đó là chính sách tốt vì thế. Tôi không thấy điểm của cái nhìn đó, mặc dù (tức là, '(? = [\\ w .-] + $)').Ngoài ra, lưu ý rằng PatternSyntaxException là một RuntimeException; bạn không bắt buộc phải bắt nó. –

0

Dưới đây là một phương pháp đó là đắt hơn (vì nó thực sự chạm vào đĩa) nhưng sẽ nền tảng chéo.

Về cơ bản, nó tạo tệp có tên đã cho và xóa tệp nếu trước đó chưa tồn tại. Nếu bạn đã cố tạo một tệp có tên không hợp lệ, nó sẽ phát ra lỗi. Vì vậy, không có vấn đề gì bạn đang ở trên hệ thống, nó sẽ cho bạn biết nếu tên tập tin là thích hợp.

Hiện tại, vi phạm quy tắc chung (sử dụng ngoại lệ để xác định luồng chương trình) và không có bất lợi khi chuyển sang đĩa. Nhưng đó là một cách tiếp cận khác và có thể cung cấp cho bạn những ý tưởng bạn có thể sử dụng.

public boolean isValidFileName(final String fileName) { 
    final File file = new File(fileName); 
    final boolean isValid = true; 
    try { 
     if (file.createNewFile()) { 
      file.delete(); 
     } 
    } catch (IOException e) { 
     isValid = false; 
    } 
    return isValid; 
} 
+0

Điều này sẽ có khả năng trả về các kết quả khác nhau trên các nền tảng khác nhau. Điều đó trái ngược với những gì thường có nghĩa là nền tảng chéo khi tôi hiểu nó. –

+0

Ý tưởng là nó cung cấp một giao diện cho chức năng phổ biến, nhưng được triển khai trên các nền tảng khác nhau. Đó là bởi vì mỗi người làm nó khác nhau mà điều này hoạt động rất tốt. Vấn đề thực sự duy nhất là khi bạn có một nền tảng nói cho một nền tảng khác là được hay không. Và như tôi đã nói đây chỉ là một ý nghĩ để đưa ra một con đường cho những ý tưởng khác. – corsiKa

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