2013-08-16 80 views
0

我写了一个正则表达式如下,其使用的提取从字符串日期:我的Java正则表达式不能正常工作

(Monday|Tuesday|Wednesday|Thursday|Friday|Saturday|Sunday)(\*){0,2}\s+\d{1,2}\s+(January|February|March|April|May|June|July|August|September|October|November|December)\s+\d{4} 

之前转换成Java正则表达式我这里测试http://regexr.com?35vlm

结果看起来没有问题,它符合我想要的。

“厄尔尼诺” 的对象是一个字符串类型的ArrayList

holiday: New Year's Day Wednesday 1 January 2014 
holiday: Chinese New Year Friday 31 January 2014 Saturday 1 February 2014 
holiday: Good Friday Friday 18 April 2014 
holiday: Labour Day Thursday 1 May 2014 
holiday: Vesak Day Tuesday 13 May 2014 
holiday: Hari Raya Puasa Monday 28 July 2014 
holiday: National Day  Saturday 9 August 2014 
holiday: Hari Raya Haji  Sunday* 5 October 2014 
holiday: Deepavali  Thursday** 23 October 2014 
holiday: Christmas Day Thursday 25 December 2014 

问题是一些Java中的日期错过了,有些是匹配的,这里我也http://java-regex-tester.appspot.com/测试,同样的错误。

更新:

我的代码的完整版:

import java.io.IOException; 
import java.text.DecimalFormat; 
import java.util.ArrayList; 
import java.util.List; 
import java.util.regex.Matcher; 
import java.util.regex.Pattern; 

import org.jsoup.Jsoup; 
import org.jsoup.nodes.Document; 
import org.jsoup.nodes.Element; 
import org.jsoup.select.Elements; 


public class Tester { 

    /** 
    * @param args 
    * @throws IOException 
    */ 
    public static void main(String[] args) throws IOException { 

     updateSingaporeHolidayCalendar(); 
    } 

public static void updateSingaporeHolidayCalendar() throws IOException{ 

     String url = "http://www.mom.gov.sg/employment-practices/leave-and-holidays/Pages/public-holidays-2014.aspx"; 
     Document document = Jsoup.connect(url).get(); 

     Elements holidays = document.select("#contentarea table tr"); 
     // System.out.println("12312312"); 
     //System.out.println("web page context: " + question); 
     List<String> el = new ArrayList<String>(); 
     for(int i = 2; i < holidays.size() + 1; i++){ 
      if((i&1) == 1) continue; 
      Elements threeGroup = holidays.get(i-2).getElementsByTag("td"); 

      int j = 2; 
      for(Element e : threeGroup){ 
       if(j-- != 0) continue; 
       j = 2; 
       el.add(e.text()); 
      } 
     } 


     Pattern pattern = Pattern.compile("(Monday|Tuesday|Wednesday|Thursday|Friday|Saturday|Sunday)(\\*){0,2}\\s+\\d{1,2}\\s+(January|February|March|April|May|June|July|August|September|October|November|December)\\s+\\d{4}"); 

     //out put 
     for(int k = 0; k < el.size(); k++){ 

      Matcher matcher = pattern.matcher(el.get(k)); 
      // Check all occurrences 
      while (matcher.find()) { 
       //System.out.print("Start index: " + matcher.start()); 
       //System.out.print(" End index: " + matcher.end()); 
       System.out.println(" Found: " + matcher.group()); 
      } 
      System.out.println("holiday: " + el.get(k)); 
     } 

    } 

} 

外部JAR:JSoup.jar

输出:

Found: Wednesday 1 January 2014 
holiday: New Year's Day Wednesday 1 January 2014 
Found: Saturday 1 February 2014 
holiday: Chinese New Year Friday 31 January 2014 Saturday 1 February 2014 
holiday: Good Friday Friday 18 April 2014 
Found: Thursday 1 May 2014 
holiday: Labour Day Thursday 1 May 2014 
holiday: Vesak Day Tuesday 13 May 2014 
holiday: Hari Raya Puasa Monday 28 July 2014 
holiday: National Day  Saturday 9 August 2014 
Found: Sunday* 5 October 2014 
holiday: Hari Raya Haji  Sunday* 5 October 2014 
holiday: Deepavali  Thursday** 23 October 2014 
Found: Thursday 25 December 2014 
holiday: Christmas Day Thursday 25 December 2014 
holiday:   
holiday:   

解决

as @Pshemo说:“你从网站获得的数据也包含无断裂空间,可以用HTML编写为 ,显然它不属于\ s类。为了解决这个问题替换每个\ s的[\ S \ u00A0]为包括该字符(具有Unicode标识符写入)“

所以表达式更改为:。

Pattern pattern = Pattern 
     .compile("(Monday|Tuesday|Wednesday|Thursday|Friday|Saturday|Sunday)(\\*){0,2}[\\s\u00A0]+\\d{1,2}[\\s\u00A0]+(January|February|March|April|May|June|July|August|September|October|November|December)[\\s\u00A0]+\\d{4}"); 

解决的问题

+1

很抱歉,但你可以多说一些关于你所面临的问题? [它似乎工作正常](http://ideone.com/kbcwgH)对我来说...没有最后两行,但因为你使用了大小2我认为这是正确的。 – Pshemo

+0

它在http://java-regex-tester.appspot.com/上也很好看。 –

+0

程序打印到控制台的输出是什么? –

回答

1

数据的所有元素,你从网站上得到遏制也no-break space可以在HTML写成&#160;,显然它循环不属于\\s类。要解决此问题,请将每个\\s替换为[\\s\u00A0]以包含此字符(用Unicode标识符编写)。

所以你的正则表达式可以像

Pattern pattern = Pattern 
     .compile("(Monday|Tuesday|Wednesday|Thursday|Friday|Saturday|Sunday)(\\*){0,2}[\\s\u00A0]+\\d{1,2}[\\s\u00A0]+(January|February|March|April|May|June|July|August|September|October|November|December)[\\s\u00A0]+\\d{4}"); 
+0

是的,你是对的,谢谢我解决了prolbem –

+0

+1非常有趣的是,与正则表达式不破坏**空间**不是一个“空间” – Bohemian

+0

@Bohemian是有趣的,但它是有意义的,因为它没有使用分隔新的行标记,制表符,但空间,使两个单词之一,所以它是一种“字母/字符”,而不是空间:) – Pshemo

0

嗯,我可以肯定地说,你会错过最后两个,因为你的迭代停止2个元素短,即改变:

k < el.size() - 2 

k < el.size() 

或更好,但使用foreach:

for (String s : el) { 
    Matcher matcher = pattern.matcher(a); 
    // ... 
} 

您正则表达式看起来OK。

+0

的更新我删除了最后2个的原因是我不需要它们,我不认为这是问题,我在java中测试过“假日:2014年4月18日星期五,星期五,星期五”,“假日:Vesak日2014年5月13日星期二“,”假日:2014年7月28日星期一Hari Raya Puasa“假日:国庆日2014年8月9日星期六”,假日:2014年10月23日星期四Deepavali假期。其他人相匹配。 –

+1

@ user1837485我刚刚测试了你的代码,它似乎工作正常。看看这里http://ideone.com/kbcwgH。 – Pshemo

+0

@Pshemo你的代码有效,一会儿,我会粘贴所有完整的代码,实际上我从网站中获取字符串列表。 –

0

您的for循环for(int k = 0; k < el.size() - 2; k++)仅限于el.size() - 2 尝试删除-2通过在列表中