2012-03-09 32 views
5

Tôi đã cố gắng tìm câu trả lời cho vấn đề của mình trong lịch sử câu hỏi nhưng họ chỉ quay lại hơn một nghìn và sau khi quét qua vài chục câu trả lời phù hợp mà tôi đã cung cấp lên. Vì vậy, đây là vấn đề của tôi.Java REGEX để khớp chính xác số chữ số trong chuỗi

Tôi muốn có thể tìm chuỗi đầu tiên chính xác sáu chữ số trong một chuỗi. Cho chuỗi “Một số văn bản 987654321 và một số văn bản khác 123456 và một số văn bản khác một lần nữa 654321 và văn bản khác ở cuối” Tôi muốn tìm regex phù hợp với chuỗi 123456.

Tôi mới dùng regex và giải thích ngắn gọn về cách hoạt động của nó sẽ giúp ích rất nhiều.

Cảm ơn bạn trước

+2

Số có sáu chữ số luôn giống nhau không? Nó sẽ luôn luôn được ngăn cách bởi không gian? Bạn có thể không cần phải sử dụng Regex ở tất cả nếu đó là trường hợp. Tôi chỉ tò mò vì bạn không chỉ rõ bản chất của số có sáu chữ số. –

+0

Tôi quan tâm đến việc tìm kiếm một chuỗi gồm 6 chữ số, bất kể chúng là số nào. Trình tự có thể được bao quanh bởi bất kỳ ký tự nào, bao gồm hoặc không phải dấu cách. Khi tôi nói bất cứ điều gì tôi có nghĩa là nó có thể có bất kỳ ký tự UTF-8. Trên thực tế chuỗi tìm kiếm của tôi là bằng tiếng Trung Phồn thể và tôi không biết nó có thể là gì. Điều quan trọng là nếu sáu chữ số là một phần của chuỗi có hơn sáu chữ số sẽ không tạo ra bất kỳ kết quả nào. – Julian

+0

Đó không phải là điều tôi muốn. 987654 là một phần của chuỗi gồm 6 chữ số (987654321) và tôi muốn loại trừ điều đó. Hy vọng nó làm rõ Cảm ơn – Julian

Trả lời

11

Bạn có thể sử dụng mô hình (?<!\d)\d{6}(?!\d), có nghĩa là "một chuỗi-vị trí đó không được đi trước bởi một chữ số; tiếp theo đúng sáu chữ số; tiếp theo là một chuỗi vị trí đó không được theo sau bằng một chữ số ". (Ký hiệu (?<!...), được biết đến như một tiêu cực lookbehind khẳng định, có nghĩa là "không trước bởi ...". Ký hiệu (?!...), được biết đến như một tiêu cực lookahead khẳng định, có nghĩa là "không tiếp theo ...". Ký hiệu \d nghĩa một chữ số. Ký hiệu {n} có nghĩa là "n lần", do đó ví dụ \d{6} có nghĩa là "sáu chữ số")

Điều đó có thể trông như thế này:.

final String number; 
{ 
    final Matcher m = Pattern.compile("(?<!\\d)\\d{6}(?!\\d)").matcher(input); 
    if(m.find()) 
     number = m.group(); // retrieve the matched substring 
    else 
     number = null; // no match found 
} 

Lưu ý: phiên bản trước của câu trả lời này đề xuất việc sử dụng các ranh giới từ, \b; nhưng một trong các nhận xét của bạn gợi ý rằng các chữ số có thể được đặt trước hoặc theo sau bởi các ký tự Trung Quốc truyền thống, được coi là ký tự từ (và do đó sẽ không kích hoạt ranh giới từ), vì vậy tôi đã thay đổi điều đó.

+0

'\ w',' \ b', ... là ASCII dựa trên java (vì vậy '\ b' của bạn đã vô tình hoạt động), bạn có thể sửa hành vi này từ Java 7 bằng cách sử dụng cờ 'UNICODE_CHARACTER_CLASS', xem [tại đây] (http://docs.oracle.com/javase/7/docs/api/java/util/regex/Pattern.html#UNICODE_CHARACTER_CLASS) – stema

+0

@stema: Trong Java, mặc dù ' \ w' là dựa trên ASCII theo mặc định, '\ b' là dựa trên Unicode. (Dunno tại sao.) – ruakh

1

Sự xuất hiện đầu tiên của 6 chữ số trong chuỗi bạn đã đăng thực sự là 987654. Nếu bạn có nghĩa là sự xuất hiện đầu tiên của 6 chữ số được bao quanh bởi các nhân vật mà không phải là chữ số, sau đó điều này sẽ làm việc:

(?<!\d)(\d{6})(?!\d) 

EDIT: phương pháp này sử dụng một lookbehind tiêu cực và một lookahead tiêu cực. Nó hơi khác so với cách tiếp cận ranh giới từ ở chỗ nó sẽ phù hợp 123456 trong chuỗi kí tự sau

123456asdf some text hello 

another string a123456 aaaaaaaa 

Nếu những con số sẽ luôn luôn được bao quanh bởi không gian sau đó từ cách tiếp cận ranh giới có lẽ là tốt hơn.

+0

Trong ví dụ của tôi, tôi đã làm rõ điều tôi muốn khớp. Có lẽ câu hỏi không rõ ràng lắm. Nhưng regex của bạn đã làm việc. Cảm ơn nhiều. – Julian

6

Các mô hình bạn đang tìm kiếm là:

(?x)    # enable comments 
(?<! \p{Nd})  # no decimal number before 
\p{Nd} {6}  # exactly six repetitions of a decimal number 
(?!= \p{Nd})  # no decimal number after 

đó cũng sẽ nhặt những thứ như

U+FF10 ‭ 0 FULLWIDTH DIGIT ZERO 
U+FF11 ‭ 1 FULLWIDTH DIGIT ONE 
U+FF12 ‭ 2 FULLWIDTH DIGIT TWO 
U+FF13 ‭ 3 FULLWIDTH DIGIT THREE 
U+FF14 ‭ 4 FULLWIDTH DIGIT FOUR 
U+FF15 ‭ 5 FULLWIDTH DIGIT FIVE 
U+FF16 ‭ 6 FULLWIDTH DIGIT SIX 
U+FF17 ‭ 7 FULLWIDTH DIGIT SEVEN 
U+FF18 ‭ 8 FULLWIDTH DIGIT EIGHT 
U+FF19 ‭ 9 FULLWIDTH DIGIT NINE 

Trong trường hợp bạn có những người trong văn bản của Trung Quốc.

+2

Rất hay: +1 để hỗ trợ toàn cầu hóa và không bị ràng buộc vào khoảng trắng. –

1
public static String splitting(String str, int num){ 
    String arr[] = str.split("[^0-9]"); 
    for(String s:arr) 
     if(s.length() == num) 
      return s; 
    return null; 
} 

thử nghiệm với

public static void main(String[] args) { 
    String s = "Some text 987654321 and some more text 123456 and some other text again 654321 and more text in the end"; 
    System.out.println(splitting(s, 6)); 
} 

ra là

123456 
0

trong Javascript console làm việc này. Xem ra cho \\d:

replacedString = "rx14ax145N".replace(RegExp("x14(?!\\d)", "g"), "___"); 

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