簡體   English   中英

編寫一個確定匹配數並提取所需字符串的正則表達式

[英]Writing a regex that determines the number of matches and extracts desired string

我正在嘗試從應該由數字空格單詞組成的字符串中提取數字

通常,該字符串應看起來像4張票 (或者也許是“ billets 2”。)

換句話說,字符串應該包含1到3個數字,一個空格和某種單詞或短語。 我只關心數字,單詞的值或它所用的語言是完全不相關的。

我的代碼另一部分需要該號碼。 它以字符串形式傳遞,因此不必擔心將其轉換為int,但是如果我需要使用標准習慣用法,我仍然可以這樣做。

為了安全起見,我認為我的代碼應該驗證只有一個數字(與數字中的數字無關),以防萬一輸入是“ 4張票子2”或類似的東西。

如何驗證字符串中是否恰好有1個數​​字(最多3個數字),以便在有其他數量的數字(尤其是根本沒有數字或一個以上的數字)時發出警告?

如果我不知道該數字在字符串中的位置,該如何提取該數字?

我從閱讀的教程中學到了很多:

String needle = "\\d{1,}";
Pattern pattern = Pattern.compile(needle);
Matcher matcher = pattern.matcher(haystack);

while(matcher.find()) {
   System.out.println("Found at: "+ matcher.start() + " - " + matcher.end());
}

這段代碼告訴我模式是否多次匹配,但是通過為每個匹配寫一行來實現,我只想知道匹配的數量。

使用以下正則表達式在文本中查找正好一個數字:

[^0-9]*([0-9]+)[^0-9]*

解釋:

[^0-9]*     match 0 or more non-digits at beginning of input
([0-9]+)    match 1 or more digits, and capture them
[^0-9]*     match 0 or more non-digits at end of input

然后,您可以使用matches()與整個輸入進行匹配。

捕獲的數字的值和位置可通過group(1)start(1)end(1)方法獲得。

測試

public static void main(String[] args) {
    test("foo  tickets 456 ");
    test("42");
    test(" 1 A 3");
    test("4 tickets");
    test("billets 2");
}
public static void test(String haystack) {
    System.out.println(haystack);
    Matcher m = Pattern.compile("[^0-9]*([0-9]+)[^0-9]*").matcher(haystack);
    if (m.matches()) {
        System.out.println("  Needle was found in positions " + m.start(1) + " thru " + m.end(1));
        System.out.println("  Number from haystack is " + m.group(1)); 
    } else {
        System.out.println("  Haystack doesn't have exactly 1 needle");
    }
}

產量

foo  tickets 456 
  Needle was found in positions 13 thru 16
  Number from haystack is 456
42
  Needle was found in positions 0 thru 2
  Number from haystack is 42
 1 A 3
  Haystack doesn't have exactly 1 needle
4 tickets
  Needle was found in positions 0 thru 1
  Number from haystack is 4
billets 2
  Needle was found in positions 8 thru 9
  Number from haystack is 2

為了從字符串中提取信息,您需要使用正則表達式組

 String haystack = "123 Foo Fighters";

 Pattern pattern = Pattern.compile("^[^\d]*(\\d{1,3})[^\\d]*$");
 Matcher matcher = pattern.matcher(haystack);

 if(matcher.find()) {
     String number = matcher.group(1);
     System.out.println(number);
 }

說明

^開始
[^ \\ d] *非數字(0或更多)
(\\ d {1,3})匹配並捕獲1到3位數字
[^ \\ d] *后跟非數字(0或更大)
$結束

我考慮了一下,並提出了一個可行的解決方案。 我不確定這是否是解決此問題的最佳方法-如果您想到了一個更好的方法,請務必予以答復-但這是:

String haystack = "foo  tickets 456 ";
String needle = "\\d{1,}+";
Pattern pattern = Pattern.compile(needle);
Matcher matcher = pattern.matcher(haystack);

int counter = 0;
int start = 0;
int end = 0; 
while(matcher.find()) {
    System.out.println("Needle '" + needle + "' found in haystack '" + haystack + "' at: "+ matcher.start() + " - " + matcher.end());
   start = matcher.start();
   end = matcher.end();
   counter++;
} 

switch (counter) {
case 1: 
    System.out.println("Needle was found in positions " + start + " thru " + end);
    String number = haystack.substring(start, end);
    System.out.println("Number from haystack is " + number); 
    break;
case 0:
    System.err.println("ERROR! Needle was not found in haystack!");
    break;
default: 
    System.err.println("ERROR: Needle was found in haystack " + counter + "   times!");     
}

我嘗試了幾次測試,包括無數字和多個數字,它似乎工作正常。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM