2015-11-03 93 views
0
java.util.regex.Pattern ips 
     = java.util.regex.Pattern.compile("(\\d{1,3}(?:\\.\\d{1,3}){2}\\.(\\d{1,3}))(?:(?:-|\\s+to\\s+)(\\d{1,3}(?![\\d\\.]))|(?:-|\\s*to\\s+)(\\d{1,3}(?:\\.\\d{1,3}){3})|\\s+(25\\d(?:\\.\\d{1,3}){3})|\\s*\\/(\\d{1,3}))?"); 

目前我正則表達式將接受下列類型的IP地址輸入,但只有一次一個輸入類型:正則表達式來捕捉這些模式的遞歸

  • IP:「47.1.2.3」
  • 範圍: 「47.1.2.3-4」
  • IP範圍: 「47.1.2.3-47.1.2.4」
  • IP到範圍: 「47.1.2.3〜4」
  • IP到IP範圍:「47.1.2.3到47.1.2.4「
  • IP CIDR: 「47.1.2.4/32」
  • IP掩碼: 「47.1.2.4 255.255.255.255」

我想修改我的正則表達式來接受用逗號分隔它們的組合或空間。理想情況下,正則表達式將命名爲上面列出的捕獲組,以使處理更容易。

我想要以下也是一個有效的輸入,但我希望能夠拉出上述與命名組匹配。

"47.1.2.3 to 4, 47.1.2.7, 47.1.3.9-47.1.3.19" 

我試圖使用正則表達式來驗證輸入到文本字段。以下代碼是文本字段:

public class HostCollectionTextField extends JFormattedTextField implements CellEditor, MouseListener { 

ArrayList listeners = new ArrayList(); 
HostCollection hc; 
java.util.regex.Pattern ips 
     = java.util.regex.Pattern.compile("(\\d{1,3}(?:\\.\\d{1,3}){2}\\.(\\d{1,3}))(?:(?:-|\\s+to\\s+)(\\d{1,3}(?![\\d\\.]))|(?:-|\\s*to\\s+)(\\d{1,3}(?:\\.\\d{1,3}){3})|\\s+(25\\d(?:\\.\\d{1,3}){3})|\\s*\\/(\\d{1,3}))?"); 

public HostCollectionTextField() { 
    this.addMouseListener(this); 
    this.hc = new HostCollection(); 

    this.setFormatterFactory(new AbstractFormatterFactory() { 

     @Override 
     public JFormattedTextField.AbstractFormatter getFormatter(JFormattedTextField tf) { 
      RegexFormatter f = new RegexFormatter(ips); 
      return f; 
     } 
    }); 
    this.getDocument().addDocumentListener(new DocListener(this)); 
    addActionListener(new ActionListener() { 
     @Override 
     public void actionPerformed(ActionEvent ae) { 
      if (stopCellEditing()) { 
       fireEditingStopped(); 
      } 
     } 
    }); 

} 

//類方法.... }

這是RegexFormatter類別:

public class RegexFormatter extends DefaultFormatter { 

protected java.util.regex.Matcher matcher; 

public RegexFormatter(java.util.regex.Pattern regex) { 
    setOverwriteMode(false); 
    matcher = regex.matcher(""); // create a Matcher for the regular expression 
} 

public Object stringToValue(String string) throws java.text.ParseException { 
    if (string == null) { 
     return null; 
    } 
    matcher.reset(string); // set 'string' as the matcher's input 

    if (!matcher.matches()) // Does 'string' match the regular expression? 
    { 
     throw new java.text.ParseException("does not match regex", 0); 
    } 

    // If we get this far, then it did match. 
    return super.stringToValue(string); // will honor the 'valueClass' property 
} 

}

+0

但它也接受列表也:https://regex101.com/r/jS2sD6/1 – Lol4t0

+0

添加更多的代碼來解釋。我將它用作輸入驗證。輸入逗號後,我的輸入不再有效。 –

+0

我不建議用逗號分割輸入,並單獨驗證每個單獨的字段,而不是一個「超級工具正常表達的完全荒謬瘋狂的複雜性」。正則表達式是很好的,所有的,但他們不是最終的瑞士軍隊的編程手段,許多人似乎認爲他們是,並試圖迫使他們進入這個角色往往有不受歡迎的和令人驚訝的影響... – twalberg

回答

1

的IP部分是非常獨特,在使用空白和/或逗號作爲分隔符的匹配過程中,重疊部分應該沒有問題(
)河

你可能需要兩個版本的相同的正則表達式。
一到驗證,一提取。

提取的只是您在全局匹配中使用的原始正則表達式。
驗證後使用。

驗證之一如下。它使用
錨點^$與使用
所需的分隔符[\s,]+之間嵌入的原始量化正則表達式一次匹配多個ip部分。

不知道這是否適用於您的驗證碼,但是如果現在輸入 單個ip部分,則應該這樣做。

驗證的正則表達式:

"^(?:\\d{1,3}(?:\\.\\d{1,3}){2}\\.\\d{1,3}(?:(?:-|\\s+to\\s+)\\d{1,3}(?![\\d\\.])|(?:-|\\s*to\\s+)\\d{1,3}(?:\\.\\d{1,3}){3}|\\s+25\\d(?:\\.\\d{1,3}){3}|\\s*\\/\\d{1,3})?(?:[\\s,]*$|[\\s,]+))+$"

格式化:

^ 
(?: 
     \d{1,3} 
     (?: \. \d{1,3}){2} 
     \. 
     \d{1,3} 
     (?: 
      (?: - | \s+ to \s+) 
      \d{1,3} 
      (?! [\d\.]) 
     | 
      (?: - | \s* to \s+) 
      \d{1,3} 
      (?: \. \d{1,3}){3} 
     | 
      \s+ 
      25 \d 
      (?: \. \d{1,3}){3} 
     | 
      \s* \/ 
      \d{1,3} 
    )? 

     (?: 
      [\s,]* $ 
     | 
      [\s,]+ 
    ) 
)+ 
$ 

編輯:添加組名稱萃取正則表達式。

# "(?<IP>\\d{1,3}(?:\\.\\d{1,3}){2}\\.(?<From_Seg>\\d{1,3}))(?:(?:-|\\s+to\\s+)(?<To_Seg>\\d{1,3}(?![\\d\\.]))|(?:-|\\s*to\\s+)(?<To_Range>\\d{1,3}(?:\\.\\d{1,3}){3})|\\s+(?<Mask>25\\d(?:\\.\\d{1,3}){3})|\\s*/(?<Port>\\d{1,3}))?" 

(?<IP>      # (1), IP 
     \d{1,3} 
     (?: \. \d{1,3}){2} 
     \. 
     (?<From_Seg> \d{1,3})  # (2), From segment 
) 
(?: 
     (?: - | \s+ to \s+) 
     (?<To_Seg>     # (3), Dash/To segment 
      \d{1,3} 
      (?! [\d\.]) 
    ) 
    | 
     (?: - | \s* to \s+) 
     (?<To_Range>     # (4), Dash/To range 
      \d{1,3} 
      (?: \. \d{1,3}){3} 
    ) 
    | 
     \s+  
     (?<Mask>      # (5), Mask 
      25 \d 
      (?: \. \d{1,3}){3} 
    ) 
    | 
     \s*/ 
     (?<Port>      # (6), Port 
      \d{1,3} 
    ) 
)? 
+0

它確實有效,但有沒有辦法拉取指定的組。即確定它與命名的捕獲組是什麼樣的匹配? –

+1

我相信你會有答案btw。您應該是Stack的正式正則表達式專家 –

+0

@JamieSnipes - 好的,將組名添加到正則表達式中。您必須研究Java正則表達式來訪問匹配器中的捕獲名稱。我認爲它與大部分的編號一樣。 – sln