2011-11-04 46 views
1

我想寫一個正則表達式,將一個字符串計數的次數在一定距離內兩個詞同時出現(在彼此的5個字)兩個詞,沒有重複計算的話。Java正則表達式查找發生併攏

舉例來說,如果我有一個字符串:

「男人喜歡他的大帽的帽子是非常大的。」

在這種情況下,正則表達式應該在第一句中看到「大帽子」,在第二句中看到「帽子大」,總共返回2個。注意,在第二句中,有「帽子」和「大」之間的幾個單詞,它們也會出現在不同的順序的第一句話,但他們仍然有5字窗口內發生。

如果正則表達式是不是解決這個問題的正確方法,請讓我知道我應該嘗試來代替。

回答

1

有點像斯蒂芬C,但使用庫類,以協助機制。

String input = "The man liked his big hat. The hat was very big"; 
    int proximity = 5; 

    // split input into words 
    String[] words = input.split("[\\W]+"); 

    // create a Deque of the first <proximity> words 
    Deque<String> haystack = new LinkedList<String>(Arrays.asList(Arrays.copyOfRange(words, 0, proximity))); 

    // count duplicates in the first <proximity> words 
    int count = haystack.size() - new HashSet<String>(haystack).size(); 
    System.out.println("initial matches: " + count); 

    // process the rest of the words 
    for (int i = proximity; i < words.length; i++) { 
     String word = words[i]; 
     System.out.println("matching '" + word + "' in [" + haystack + "]"); 

     if (haystack.contains(word)) { 
      System.out.println("matched word " + word + " at index " + i); 
      count++; 
     } 

     // remove the first word 
     haystack.removeFirst(); 
     // add the current word 
     haystack.addLast(word); 
    } 

    System.out.println("total matches:" + count); 
1

如果正則表達式不是解決此問題的正確方法,請讓我知道我應該嘗試的是什麼。

正則表達式可能工作,但他們不是最好的方式來做到這一點。

一個更好的辦法來做到這一點是打破輸入字符串轉換成單詞序列(例如使用String.split(...)),然後遍歷序列是這樣的:

String[] words = input.split("\\s"); 
int count = 0; 
for (int i = 0; i < words.length; i++) { 
    if (words[i].equals("big")) { 
     for (int j = i + 1; j < words.length && j - i < 5; j++) { 
      if (words[j].equals("hat")) { 
       count++; 
      } 
     } 
    } 
} 
// And repeat for "hat" followed by "big". 

則可能需要根據變化正是你想要數的東西,但這是一般的想法。


如果您需要爲許多單詞組合這麼做,那麼值得尋找更有效的解決方案。但作爲一次性或小批量用例,最簡單是最好的。

+0

我正在考慮這樣的事情,但它似乎有點蠻力十歲上下,我也相信它最終會重複計算一些字。 –

0

此正則表達式匹配的內彼此

([a-zA-Z]+)(?:[^ ]*){0,5}\1[^a-zA-Z] 
  • ([a-zA-Z]+) 5個字的兩個單詞每次出現時同時出現將匹配字如果可以etheir匹配[0-9]中你可以替換你的話([a-zA-Z0-9] +)。

  • (?:[^ ]*){0,5}匹配介於0和5個字

  • \1[^a-zA-Z]以匹配您的詞的重複

然後你可以用一個模式使用,並找到repetited字

的每種情況
1

嘖嘖......在其他的答案全部是代碼...這個怎麼樣一個在線解決方案:

int count = input.split("big(\\b.*?){1,5}hat").length + input.split("hat(\\b.*?){1,5}big").length - 2; 
+0

你需要知道你正在尋找哪些單詞。 – ptomli