2016-09-21 115 views
-2

我試圖以匹配所有包含符號<>令牌,但也有一些衝突。特別是,我的令牌是<,>,</,/>,以及以<!--開始並以-->結束的評論。是正則表達式匹配的衝突重疊符號

我對這些正則表達式如下:

String LTHAN = "<"; 
String GTHAN = ">"; 
String LTHAN_SLASH = "</"; 
String GTHAN_SLASH = "/>"; 
String COMMENT = "<!--.*-->"; 

而且我用的一般方法,將它們添加到列表編譯它們:

public void add(String regex, int token) { 
    tokenInfos.add(new TokenInfo(Pattern.compile("^(" + regex + ")"), token)); 
} 

這裏是我的TokenInfo類的樣子:

private class TokenInfo { 
    public final Pattern regex; 
    public final int token; 

    public TokenInfo(Pattern regex, int token) { 
     super(); 
     this.regex = regex; 
     this.token = token; 
    } 
} 

我匹配並顯示如下列表:

public void tokenize(String str) { 
    String s = new String(str); 
    tokens.clear(); 
    while (!s.equals("")) { 
     boolean match = false; 

     for (TokenInfo info : tokenInfos) { 
      Matcher m = info.regex.matcher(s); 
      if (m.find()) { 
       match = true; 

       String tok = m.group().trim(); 
        tokens.add(new Token(info.token, tok)); 

       s = m.replaceFirst(""); 
       break; 
      } 
     } 
    } 
} 

讀取和顯示:

try { 
     BufferedReader br; 
     String curLine; 
     String EOF = null; 
     Scanner scan = new Scanner(System.in); 
     StringBuilder sb = new StringBuilder(); 

     try {  
      File dir = new File("C:\\Users\\Me\\Documents\\input files\\example.xml"); 
      br = new BufferedReader(new FileReader(dir)); 

      while ((curLine = br.readLine()) != EOF) { 
       sb.append(curLine); 
       // System.out.println(curLine); 
      } 
      br.close(); 
     } catch (IOException e) { 
      System.out.println(e.getMessage()); 
     } 

     tokenizer.tokenize(sb.toString()); 

     for (Tokenizer.Token tok : tokenizer.getTokens()) { 
      System.out.println("" + tok.token + " " + tok.sequence); 
     } 
    } catch (Exception e) { 
     System.out.println(e.getMessage()); 
    } 
} 

樣品輸入:

<!-- Sample input file with incomplete recipe --> 
<recipe name="bread" prep_time="5 mins" cook_time="3 hours"> 
    <title>Basic bread</title> 
    <ingredient amount="3" unit="cups">Flour</ingredient> 
    <instructions> 
    <step>Mix all ingredients together.</step> 
    </instructions> 
</recipe> 

然而,輸出令牌列表識別</(包括任何字符來後話)作爲單獨的令牌,意思它似乎永遠不會識別令牌<//>。與評論相同的問題。這是我的正則表達式的問題嗎?爲什麼它不識別模式<//>

希望我的問題是清楚的。如有需要,歡迎提供更多細節/示例。

+0

它們是否按聲明的順序添加到列表中? – RamenChef

+2

如果您嘗試解析HTML/XML,我建議使用現有的庫。 – 4castle

+0

您可能想提及'TokenInfo'和'Pattern'的來源。 (假設oAuth&java.util,但是...可能是錯誤的) – Tibrogargan

回答

1

問題:

  1. 您最初的正則表達式^(<)將匹配對整個輸入。這個正則表示文本必須以<開頭,整個輸入字符串就是這樣。所以你將不得不修復它。
  2. 如果整個標籤(沒有文字內容 - 如基本面包,將所有配料混合在一起)被視爲令牌。所以相應的正則表達式應該是一個單一的正則表達式。

嘗試改變正則表達式爲以下:

  1. 對於單一的標記 - <[^>]*>
  2. 對於單一的關閉標籤 - </[^]*>;
  3. 徵求意見 - <! - 。* - >(這已經是正確的)

示例程序

import java.io.BufferedReader; 
import java.io.File; 
import java.io.FileReader; 
import java.io.IOException; 
import java.util.ArrayList; 
import java.util.HashMap; 
import java.util.Map.Entry; 
import java.util.regex.Matcher; 
import java.util.regex.Pattern; 

public class RegexTest { 
    private static ArrayList<TokenInfo> tokenInfoList = new ArrayList<>(); 
    private static ArrayList<String> tokensList = new ArrayList<>(); 

    public static void add(String regex, int token) { 
     tokenInfoList.add(new TokenInfo(Pattern.compile(regex), token)); 
    } 

    static { 
     String LTHAN = "<[^>]*>"; 
     String LTHAN_SLASH = "</[^>]*>"; 
     String COMMENT = "<!--.*-->"; 
     add(LTHAN, 1); 
     add(LTHAN_SLASH, 3); 
     add(COMMENT, 5); 
    } 

    private static class TokenInfo { 
     public final Pattern regex; 
     public final int token; 

     public TokenInfo(Pattern regex, int token) { 
      super(); 
      this.regex = regex; 
      this.token = token; 
     } 
    } 

    public static void tokenize(String str) { 
     String s = new String(str); 
     while (!s.equals("")) { 
      boolean match = false; 
      for (TokenInfo info : tokenInfoList) { 
       Matcher m = info.regex.matcher(s); 
       if (m.find()) { 
        match = true; 
        String tok = m.group().trim(); 
        tokensList.add(tok); 
        s = m.replaceFirst(""); 
        break; 
       } 
      } 
      // The following is under the assumption that the Text nodes within the document are not considered tokens and replaced 
      if (!match) { 
       break; 
      } 
     } 
    } 

    public static void main(String[] args) { 
     try { 
      BufferedReader br; 
      String curLine; 
      String EOF = null; 
      StringBuilder sb = new StringBuilder(); 

      try { 
       File dir = new File("/home/itachi/Desktop/recipe.xml"); 
       br = new BufferedReader(new FileReader(dir)); 

       while ((curLine = br.readLine()) != EOF) { 
        sb.append(curLine); 
        // System.out.println(curLine); 
       } 
       br.close(); 
      } catch (IOException e) { 
       System.out.println(e.getMessage()); 
      } 

      tokenize(sb.toString()); 

      for (String eachToken : tokensList) { 
       System.out.println(eachToken); 
      } 
     } catch (Exception e) { 
      System.out.println(e.getMessage()); 
     } 
    } 
} 

參考

http://www.regular-expressions.info/是學習正則表達式的重要資源。

+0

我的朋友,我感謝你的這一點。而不是質疑和判斷我的工作,你實際上借給我一隻手。我非常感激。 –