2014-06-16 50 views
1

量詞x?表示a single or no occurance of xx?量詞:爲什麼非x給出「零長度」匹配?

爲了方便起見,我發佈了一個test harness用於匹配正則表達式和字符串。

與字符串ababaaaab相比,我對正則表達式a?感到困惑。

程序的輸出是:

Enter your regex: a? 

Enter your input string to seacrh: ababaaaab 

I found the text "a" starting at index 0 and ending at index 1. 
I found the text "" starting at index 1 and ending at index 1. 
I found the text "a" starting at index 2 and ending at index 3. 
I found the text "" starting at index 3 and ending at index 3. 
I found the text "a" starting at index 4 and ending at index 5. 
I found the text "a" starting at index 5 and ending at index 6. 
I found the text "a" starting at index 6 and ending at index 7. 
I found the text "a" starting at index 7 and ending at index 8. 
I found the text "" starting at index 8 and ending at index 8. 
I found the text "" starting at index 9 and ending at index 9. 

Enter your regex: 

我感到困惑的B的。

「?正則表達式一個沒有特別尋找信 ‘B’;它僅僅尋找 字母的存在(或缺乏)的‘a’。如果量詞允許。匹配「a」零次, 輸入字符串中不是「a」的任何內容都將顯示爲 零長度匹配。「

Reference

問題: -

第一行是可以理解的,並且我明白B或任何非一個的這種存在是不存在的,或0 occurence的,所以應該導致匹配。 但是沒有(即b的出現)在指數1和2之間。那麼,爲什麼指數1和指數1之間的文字「匹配」(換句話說,爲什麼我們會得到一個零 - 全長比賽在這裏)。從我的推理,應該是指數1和2


import java.io.InputStreamReader; 
import java.util.Scanner; 
import java.util.regex.Matcher; 
import java.util.regex.Pattern; 

/* 
* Enter your regex: foo 
* Enter input string to search: foo 
* I found the text foo starting at index 0 and ending at index 3. 
* */ 

public class RegexTestHarness { 

    public static void main(String[] args){ 

     /*Console console = System.console(); 
     if (console == null) { 
      System.err.println("No console."); 
      System.exit(1); 
     }*/ 

     while (true) { 

      /*Pattern pattern = 
      Pattern.compile(console.readLine("%nEnter your regex: ", null));*/ 

      System.out.print("\nEnter your regex: "); 

      Scanner scanner = new Scanner(new InputStreamReader(System.in)); 

      Pattern pattern = Pattern.compile(scanner.next()); 

      System.out.print("\nEnter your input string to seacrh: "); 

      Matcher matcher = 
      pattern.matcher(scanner.next()); 

      boolean found = false; 
      while (matcher.find()) { 
       /*console.format("I found the text" + 
        " \"%s\" starting at " + 
        "index %d and ending at index %d.%n", 
        matcher.group(), 
        matcher.start(), 
        matcher.end());*/ 

       System.out.println("I found the text \"" + matcher.group() + "\" starting at index " + matcher.start() + " and ending at index " + matcher.end() + "."); 

       found = true; 
      } 
      if(!found){ 
       //console.format("No match found.%n", null); 
       System.out.println("No match found."); 
      } 
     } 
    } 
} 

回答

1

但缺少的(即B的次數)之間是指數1和2,爲什麼之間是索引1和1之間的文本「」的匹配(換句話說,爲什麼我們在這裏得到零長度匹配)

匹配的長度是匹配的輸入字符串的長度該模式。

由於沒有「a」,只有一個空字符串被匹配。

此外,該模式不匹配「一個非字符序列」,它匹配一個長度爲1的(可能爲空)「a」序列。在這種情況下,匹配序列是空的。

但不存在的(即B的次數)

缺乏的是 B的一次出現。發生缺席之前發生b並結束於b發生。

+0

爲了'b'還是不要''b ...好的答案。 – Mena

+0

另外,將它與模式'[^ a]'進行比較,它匹配「非-a」。 – laune

+0

@Mena 2 b || ¬2 b ;-) – laune

1

位置報道是不是性格

最關鍵的事情要明白的是,正則表達式引擎是不是給你一個角色在那裏找到了匹配的位置的位置。

它給了你開始成功比賽的起始位置。那個位置不是一個角色。這是人物之間的空間。例如,

  • 位置0是字符串的最開始。這就是\A^聲明匹配的地方。
  • 位置1是第一個和第二個字符之間的位置。
  • 位置9是在ababaaaab末尾的最後一個b之後的位置。這就是\Z$斷言匹配的地方。
+0

...和9在最後一個字符之後,並且$'匹配。 – laune

+0

@laune是的,沒錯。好主意補充一點。謝謝。 :) – zx81

0

a?是貪婪的。換句話說,正則表達式引擎將處理如下:

foreach index 
    if next char is "a" 
     return "a" 
    else if next char is "" 
     return "" 
    end if 
end foreach 

如果您在輸入字符串應用此算法,你必須在輸出時提供的相同。


你可以試試它的非貪婪(或懶惰)等價物:a??。正則表達式引擎將然後過程如下:

foreach index 
    if next char is "" 
     return "" 
    else if next char is "a" 
     return "a" 
    end if 
end foreach 

空字符串將因此各索引處找到,並且沒有a將在所有被輸出。

相關問題