簡體   English   中英

包含Java中所有特定字母的正則表達式

[英]Regular Expression That Contains All Of The Specific Letters In Java

我有一個正則表達式,可以選擇包含所有 (而不是任何)特定字母的所有單詞,在Notepad ++上可以正常使用。

正則表達式模式

^(?=.*B)(?=.*T)(?=.*L).+$

輸入文本文件;

AL
BAL
BAK
LABAT
TAL
LAT
BALAT
LA
AB
LATAB
TAB

並在notepad ++中輸出正則表達式;

LABAT
BALAT
LATAB

由於它對Notepad ++很有用,因此我在Java上嘗試了相同的正則表達式,但失敗了。

這是我的測試代碼;

import java.util.regex.Matcher;
import java.util.regex.Pattern;
import com.lev.kelimelik.resource.*;

public class Test {

    public static void main(String[] args) {
        String patternString = "^(?=.*B)(?=.*T)(?=.*L).+$";

        String dictionary = 
                "AL" + "\n"
                +"BAL" + "\n"
                +"BAK" + "\n"
                +"LABAT" + "\n"
                +"TAL" + "\n"
                +"LAT" + "\n"
                +"BALAT" + "\n"
                +"LA" + "\n"
                +"AB" + "\n"
                +"LATAB" + "\n"
                +"TAB" + "\n";

        Pattern p = Pattern.compile(patternString, Pattern.DOTALL);
        Matcher m = p.matcher(dictionary);
        while(m.find())
        {
            System.out.println("Match: " + m.group());
        }
    }

}

輸出是錯誤的 ,如下所示;

Match: AL
BAL
BAK
LABAT
TAL
LAT
BALAT
LA
AB
LATAB
TAB

我的問題很簡單,此正則表達式的java兼容版本是什么?

Pattern更改為:

String patternString = ".*(?=.*B)(?=.*L)(?=.*T).*";

產量

Match: LABAT
Match: BALAT
Match: LATAB

特定於Java的答案

在現實生活中,我們幾乎不需要驗證 ,而我看到實際上,您只是將輸入用作測試數據的數組。 最常見的情況是逐行讀取輸入並對其進行檢查。 我同意在Notepad ++中會有些不同,但是在Java中,應單獨檢查一行。

也就是說,您不應在不同平台上復制相同的方法。 在Notepad ++中有什么用Java不一定要有好處。

我建議這種幾乎不使用正則表達式的方法( String#split()仍使用它):

String dictionary_str = 
        "AL" + "\n"
        +"BAL" + "\n"
        +"BAK" + "\n"
        +"LABAT" + "\n"
        +"TAL" + "\n"
        +"LAT" + "\n"
        +"BALAT" + "\n"
        +"LA" + "\n"
        +"AB" + "\n"
        +"LATAB" + "\n"
        +"TAB" + "\n";
String[] dictionary = dictionary_str.split("\n"); // Split into lines
for (int i=0; i<dictionary.length; i++)   // Iterate through lines
{
    if(dictionary[i].indexOf("B") > -1 && // There must be B
       dictionary[i].indexOf("T") > -1 && // There must be T
       dictionary[i].indexOf("L") > -1)   // There must be L
    {
        System.out.println("Match: " + dictionary[i]); // No need matching, print the whole line
    }
}

IDEONE演示

基於正則表達式的原始答案

您永遠不要依賴.* 這種構造總是導致回溯問題。 在這種情況下,您可以使用否定的字符類所有格 修飾符輕松地對其進行優化:

^(?=[^B]*+B)(?=[^T]*+T)(?=[^L]*+L)

正則表達式細分:

  • ^ -字符串開頭
  • (?=[^B]*+B) -在字符串的開頭,請檢查是否至少有一個B存在,其后可能有0個或多個除B以外的字符
  • (?=[^T]*+T) - 仍然在字符串的開頭,請檢查是否至少有一個T存在,其前面可能有0個或多個T以外的字符
  • (?=[^L]*+L) - 仍然在字符串的開頭,請檢查是否存在至少一個L ,該L可能以L以外的0個或多個字符開頭

參見Java演示

String patternString = "^(?=[^B]*+B)(?=[^T]*+T)(?=[^L]*+L)";
String[] dictionary = {"AL", "BAL", "BAK", "LABAT", "TAL", "LAT", "BALAT", "LA", "AB", "LATAB", "TAB"};
for (int i=0; i<dictionary.length; i++)
{
    Pattern p = Pattern.compile(patternString);
    Matcher m = p.matcher(dictionary[i]);
    if(m.find())
    {
        System.out.println("Match: " + dictionary[i]);
    }
}

輸出:

Match: LABAT
Match: BALAT
Match: LATAB

我沒有調試您的情況,但我認為您的問題是由匹配整個字符串而不是單個單詞引起的。

您要匹配"AL\\nBAL\\nBAK\\nLABAT\\n"以及其他內容。 當然,該字符串具有所有必需的字符。 您可以看到以下事實:您的輸出僅包含一個Match:前綴。

請看看這個答案。 您需要使用Pattern.MULTILINE

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM