簡體   English   中英

Java正則表達式匹配具有特殊字符的精確單詞

[英]Java Regular Expression to Match Exact Word with Special Characters

我有用戶輸入的關鍵字列表,它們可能包含特殊字符,如$, #, @, ^, &,等。

根據我的要求,當我收到短信列表時,我需要搜索每條短信中的所有關鍵字。

我們需要匹配完全關鍵字

案例1:簡單關鍵字 - 簡單消息

我使用\\b匹配完全關鍵字,它工作正常。

public static void main(String[] args) {
        String patternStr =  "(?i)\\bHello\\b";

        Pattern pattern = Pattern.compile(patternStr);

        List<String> strList = new ArrayList<String>();
        strList.add("HHello Message");
        strList.add("This is Hello Message ");
        strList.add("Now Hellos again.");

        for(String str : strList) {
            Matcher matcher = pattern.matcher(str);
            System.out.println(">> "+matcher.find());
        }
    }

按預期輸出

>> false
>> true
>> false

案例2:簡單關鍵字 - 具有特殊字符的消息

現在,如果我在跟蹤消息上面運行相同的代碼,那么它沒有按預期工作

List<String> strList = new ArrayList<String>();
strList.add("#Hello Message");
strList.add("This is Hello Message ");
strList.add("Now Hellos again.");

OUTPUT:

true
true
false

預計輸出

false
true
false

案例3:具有特殊字符的關鍵字和消息

如果我收到以下消息,關鍵字是#Hello 我寫了下面的代碼,但它沒有用

public static void main(String[] args) {
        String patternStr =  "(?i)\\b#Hello\\b";

        Pattern pattern = Pattern.compile(patternStr);

        List<String> strList = new ArrayList<String>();
        strList.add("HHello Message");
        strList.add("This is #Hello Message ");
        strList.add("Now Hellos again.");

        for(String str : strList) {
            Matcher matcher = pattern.matcher(str);
            System.out.println(">> "+matcher.find());
        }
    }

OUTPUT:

>> false
>> false
>> false

預期產量:

>> false
>> true
>> false

如何逃避特殊字符並解決CASE 2 and CASE 3

請幫忙。

案例2與案例3相反,所以我不認為你可以結合Pattern

對於案例2,您的Pattern可能如下所示:

Pattern pattern = Pattern.compile("(\\s|^)Hello(\\s|$)", Pattern.CASE_INSENSITIVE);

在這種情況下,我們用空格或輸入的開頭/結尾包圍關鍵字。

對於案例3,您的Pattern可能如下所示:

Pattern pattern = Pattern.compile("[\\$#@\\^&]Hello(\\s|$)", Pattern.CASE_INSENSITIVE);

在這種情況下,我們在關鍵字前面加上您選擇的任何特殊字符(注意轉義的保留字符$^ ),然后我們接受空格或輸入的結尾作為關鍵字后面的字符。

使用(?:^|\\s) (“文本或空白的開頭”)代替第一個\\b(?:$|\\s) (“文本結尾或空白”)而不是第二個\\b in你的正則表達式。

問題來自定義“確切詞”的方式。 它不僅僅是可以圍繞單詞的空白,使它成為一個單詞。 例如,在大多數情況下,人們可能希望使用“Hello”的精確單詞匹配。

“那你好”,“那個年輕人剛跟那個年輕人打招呼”和“我希望人們仍然會說你好,而不是你好。”

如果您希望僅在空格上拆分匹配,那么我相信您必須指定空白條件。 假設你也想在最后匹配那么我會提出這樣的事情。

Pattern pattern = Pattern.compile("\(^\| \)" + escapeSearchString(patternString) + "\( \|$\)");

然后有幾個像這樣的方法

public String escapeSearchString(String patternString) {
    StringBuilder stringBuilder = new StringBuilder(patternString.length() * 3);
    for (char c : patternString.toCharArray()) {
        if (isEscapableCharacter(c)) {
            stringBuilder.append("\\");
        }
        stringBuilder.append(c);
    }
}

public boolean isEscapableCharacter(char c) {
    switch (c) {
        case '#':
        case '$':
        case '@':
        case '^':
        case '&':
            return true;
        default:
            return false;
    }
}

為可逃避的字符迭代char []並從配置文件加載它們可能會更好。

也許這樣試試吧

String patternStr = "(?i)(?<=\\s|^)"+Pattern.quote(searchedStubstring)+"(?=\\s|$)";

(?<= ...)和(?= ...)是積極的看后面和前面所以它會檢查你的searchedStubstring是否會有

  • 白色空間\\\\s\\\\s之前的輸入^開始,和
  • white-space \\\\s或輸入結束&之后。

如果你想搜索像$ +和其他人這樣的特殊字符,你需要逃避它們。 為此,您可以使用Pattern.quote(searchedStubstring)

例如,如果你的單詞想要在開頭和結尾有特殊字符(例如這里'#'),你必須寫下面的內容:

Pattern p = Pattern.compile("(\\s|^|#)"+word+"(\\s|\\#|$)", Pattern.CASE_INSENSITIVE);

如果你想要完全匹配:

Pattern p = Pattern.compile("(\\s|^)"+word+"(\\s|$)", Pattern.CASE_INSENSITIVE);

用'|' 就像OR那樣你可以添加你想要的匹配特殊字符..例如:

Pattern p = Pattern.compile("(\\s|^|#|:|-)"+word+"(\\s|\\#|\\,|\\.|$)", Pattern.CASE_INSENSITIVE);

char'^'表示在行開頭檢測字符串,'$'表示在行尾。 在這里看到更多: 正則表達式構造的摘要

暫無
暫無

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

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