2016-02-03 239 views
0

我正在製作一個Lexer,並選擇使用正則表達式來分割我的令牌。正則表達式 - 包含多個下劃線的單詞

我正在處理所有不同的標記,除了真正讓我感到困惑的標記是單詞和標識符

你看,我已經制定的規則如下:

  • 詞不能啓動或下劃線結束。
  • 單詞的長度可以是一個或多個字符。
  • 下劃線只能用於之間的之間的字母,並且可以多次出現。我想要什麼

例子:

_foo   <- Invalid. 
foo_   <- Invalid. 
_foo_  <- Invalid. 
foo_foo  <- Valid. 
foo_foo_foo <- Valid. 
foo_foo_  <- Partially Valid. Only "foo_foo" should be picked up. 
_foo_foo  <- Partially Valid. Only "foo_foo" should be picked up. 

我越來越近,因爲這是我目前有:

([a-zA-Z]+_[a-zA-Z]+|[a-zA-Z]+)

除此之外,它只能檢測中第一次出現下劃線。我想要所有人。

個人的要求:

我寧願答案被包含在一個組裏,因爲我已經構建我的身邊tokeniser,但我會很樂意改變我的設計,如果你能想到的更好的處理方式。這是我目前使用:

private void tokenise(String regex, String[] data) { 
    Set<String> tokens = new LinkedHashSet<String>(); 
    Pattern pattern = Pattern.compile(regex); 
    // First pass. Uses regular expressions to split data and catalog token types. 
    for (String line : data) { 
     Matcher matcher = pattern.matcher(line); 
     while (matcher.find()) { 
      for (int i = 1; i < matcher.groupCount() + 1; i++) { 
       if (matcher.group(i) != null) { 
        switch(i) { 
        case (1): 
         // Example group. 
         // Normally I would structure like: 
         // 0: Identifiers 
         // 1: Strings 
         // 2-?: So on so forth. 
         tokens.add("FOO:" + matcher.group()); 
         break; 
        } 
       } 
      } 
     } 
    } 
} 

回答

5

嘗試([a-zA-Z]+(?:_[a-zA-Z]+)*)

格局,[a-zA-Z]+的第一部分,一個或多個字母匹配。
該模式的第二部分(?:_[a-zA-Z]+)與後跟一個或多個字母的非內容匹配。
末尾的*表示第二部分可以重複零次或多次。
(?:)與普通()類似,但不返回匹配的組。

+1

哦,我的天啊!謝謝。你能解釋一下你對我做了什麼不同嗎? – finnrayment

+0

如果你不使用'String#matches()',或者你想查找單詞,而不是更大文本中的標識符,這個正則表達式也會匹配'_foo'中的'foo'。不確定是否有預期。 –

+0

@frayment該模式的第一部分「[a-zA-Z] +'匹配一個或多個字母。該模式的第二部分「(?:_ [a-zA-Z] +)」匹配一個不希望的結果,如果後面跟着一個或多個字母。 *末尾意味着第二部分可以重複零次或多次。 '(?:)'就像普通的'()',但不會返回匹配的組。 – RootTwo

相關問題