2008-12-16 39 views
19

Tôi muốn sử dụng regex với Java.Regex để tìm số nguyên trong một chuỗi

Điều tôi muốn làm là tìm số nguyên đầu tiên trong chuỗi.

Ví dụ:

String = "the 14 dogs ate 12 bones" 

Would return 14.

String = "djakld;asjl14ajdka;sdj" 

cũng Would return 14.

Đây là những gì tôi có cho đến nay.

Pattern intsOnly = Pattern.compile("\\d*"); 
Matcher makeMatch = intsOnly.matcher("dadsad14 dssaf jfdkasl;fj"); 
makeMatch.find(); 
String inputInt = makeMatch.group(); 
System.out.println(inputInt); 

Tôi đang làm gì sai?

Trả lời

48

Bạn đang yêu cầu 0 hoặc nhiều chữ số. Bạn cần phải yêu cầu 1 hoặc nhiều hơn:

"\\d+" 
0

Đó là một tiện ích tôi đã tạo cho C# với generics. Nó sẽ phù hợp dựa trên biểu hiện thường xuyên của bạn và gửi lại các loại bạn cần:

public T[] GetMatches<T>(string Input, string MatchPattern) where T : IConvertible 
    { 
     List<T> MatchedValues = new List<T>(); 
     Regex MatchInt = new Regex(MatchPattern); 

     MatchCollection Matches = MatchInt.Matches(Input); 
     foreach (Match m in Matches) 
      MatchedValues.Add((T)Convert.ChangeType(m.Value, typeof(T))); 

     return MatchedValues.ToArray<T>(); 
    } 

sau đó nếu bạn muốn lấy chỉ số và trả lại trong một string [] array:

string Test = "22$data44abc"; 
string[] Matches = this.GetMatches<string>(Test, "\\d+"); 

Hy vọng rằng đây hữu ích cho ai đó ...

3

Dường như các giải pháp khác không xử lý được +/- và các trường hợp như 2e3, hỗ trợ java.lang.Integer.parseInt(String), vì vậy tôi sẽ giải quyết vấn đề. Tôi hơi thiếu kinh nghiệm ở regex, vì vậy tôi có thể đã mắc phải một vài sai lầm, sử dụng thứ gì đó mà trình phân tích cú pháp regex của Java không hỗ trợ, hoặc làm cho nó quá phức tạp, nhưng các câu lệnh dường như hoạt động trong Kiki 0.5.6.

Tất cả các cụm từ thông dụng đều được cung cấp ở cả định dạng không thoát để đọc và định dạng thoát mà bạn có thể sử dụng làm chuỗi ký tự trong Java.

Để có được một byte, short, int, hoặc dài từ một chuỗi:

unescaped: ([\+-]?\d+)([eE][\+-]?\d+)? 
    escaped: ([\\+-]?\\d+)([eE][\\+-]?\\d+)? 

... và cho điểm thưởng ...

Để có được một đôi hoặc phao từ một chuỗi:

unescaped: ([\+-]?\d(\.\d*)?|\.\d+)([eE][\+-]?(\d(\.\d*)?|\.\d+))? 
    escaped: ([\\+-]?\\d(\\.\\d*)?|\\.\d+)([eE][\\+-]?(\\d(\\.\\d*)?|\\.\\d+))? 
+0

Điều này vẫn giữ số như 099, trong đó java parseInt sẽ ném NumberFormatException. –

+0

Tôi phải hiểu lầm bạn. '099' được chuyển đổi thành 99 bằng' Integer.parseInt() ', xem: http://pastie.org/1881188 – bgw

+0

Điều này vẫn hoạt động khi con số nằm trong một chuỗi như" 2-1 "? Nó sẽ tìm đúng kết quả đầu tiên "2", nhưng trận đấu thứ hai "-1" không chính xác vì có - là toán tử. Bạn sẽ cần phải sử dụng một cái gì đó thậm chí fancier (liên quan đến một lookbehind rằng sẽ disinclude một + hoặc - nếu ngay trước đó cũng là một số) – AJMansfield

0

Ngoài những gì PiPeep cho biết, nếu bạn đang cố gắng khớp số nguyên trong một biểu thức, do đó 1 + 2 - 3 sẽ chỉ phù hợp 1, 2, và 3, chứ không phải là 1, + 2- 3, bạn thực sự cần phải sử dụng một tuyên bố lookbehind, và phần bạn muốn thực sự sẽ được trả lại bởi Matcher.group(2) thay vì chỉ Matcher.group() .

unescaped: ([0-9])?((?(1)(?:[\+-]?\d+)|)(?:[eE][\+-]?\d+)?) 
    escaped: ([0-9])?((?(1)(?:[\\+-]?\\d+)|)(?:[eE][\\+-]?\\d+)?) 

Ngoài ra, cho những thứ như someNumber - 3, nơi someNumber là một tên biến hoặc một cái gì đó như thế, bạn có thể sử dụng

unescaped: (\w)?((?(1)(?:[\+-]?\d+)|)(?:[eE][\+-]?\d+)?) 
    escaped: (\\w)?((?(1)(?:[\\+-]?\\d+)|)(?:[eE][\\+-]?\\d+)?) 

Mặc dù tất nhiên điều đó không làm việc, nếu bạn đang phân tích một chuỗi như The net change to blahblah was +4

+0

Tôi không thấy bất kỳ lookbehinds trong những regexes. Những gì tôi thấy là [điều kiện] (http://www.regular-expressions.info/conditional.html), không được hỗ trợ trong Java. –

+0

Ohhhh ... đó là lý do tại sao chương trình của tôi không hoạt động ... – AJMansfield

0

thông số java thực sự cung cấp cho con quái vật này của một regex để phân tích cú pháp đôi. tuy nhiên nó được coi là thực hành xấu, chỉ cần cố gắng phân tích cú pháp với loại dự định và bắt lỗi, có xu hướng dễ đọc hơn một chút.

DOUBLE_PATTERN = Pattern 
     .compile("[\\x00-\\x20]*[+-]?(NaN|Infinity|((((\\p{Digit}+)(\\.)?((\\p{Digit}+)?)" 
       + "([eE][+-]?(\\p{Digit}+))?)|(\\.((\\p{Digit}+))([eE][+-]?(\\p{Digit}+))?)|" 
       + "(((0[xX](\\p{XDigit}+)(\\.)?)|(0[xX](\\p{XDigit}+)?(\\.)(\\p{XDigit}+)))" 
       + "[pP][+-]?(\\p{Digit}+)))[fFdD]?))[\\x00-\\x20]*"); 
Các vấn đề liên quan