我有用户输入的关键字列表,它们可能包含$, #, @, ^, &,
等特殊字符。
根据我的要求,当我收到短信列表时,我需要搜索每条短信中的所有关键字。
我们需要匹配完全关键字。
案例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.");
输出:
true
true
false
预期的输出
false
true
false
案例3:关键字&amp;具有特殊字符的消息
如果我收到以下消息且关键字为#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());
}
}
输出:
>> false
>> false
>> false
预期的输出:
>> false
>> true
>> false
如何逃避特殊字符并解析 CASE 2 and CASE 3
。
请帮忙。
答案 0 :(得分: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);
在这种情况下,我们在关键字前面加上您选择的任何特殊字符(请注意转义的保留字符$
和^
),然后我们接受空格或输入结束作为关键字后面的字符。
答案 1 :(得分:2)
使用(?:^|\s)
(“文字或空格的开头”)代替第一个\b
和(?:$|\s)
(“文字末尾或空格”)而不是第二个{{1}在你的正则表达式中。
答案 2 :(得分:1)
问题来自定义“确切词”的方式。它不仅仅是可以围绕单词的空白,使它成为一个单词。例如,在大多数情况下,人们可能希望使用“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 []并从配置文件加载它们可能会更好。
答案 3 :(得分:1)
尝试这种方式
String patternStr = "(?i)(?<=\\s|^)"+Pattern.quote(searchedStubstring)+"(?=\\s|$)";
(?&lt; = ...)和(?= ...)为正look behind and ahead因此会检查您searchedStubstring
之前是否有
\\s
或之前输入^
的开头,以及\\s
或其后的输入&
的结尾。如果您想搜索特殊字符,例如$
+
和其他人,则需要将其删除。为此,您可以使用Pattern.quote(searchedStubstring)
答案 4 :(得分:0)
例如,如果你的单词想要在开头和结尾有特殊字符(例如这里'#'),你必须写下以下内容:
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'^'表示在行开头检测字符串,'$'表示在行尾。 在这里看到更多: Summary of regular-expression constructs