【问题标题】:Matching a word with pound (#) symbol in a regex在正则表达式中匹配带有井号 (#) 符号的单词
【发布时间】:2016-12-30 13:17:28
【问题描述】:

我有正则表达式来检查某些文本是否包含单词(忽略边界)
String regexp = ".*\\bSOME_WORD_HERE\\b.*"; 但是当“SOME_WORD”以#(井号)开头时,这个正则表达式返回false

Example, without #   
String text = "some text and test word";
String matchingWord = "test";
boolean contains = text.matches(".*\\b" + matchingWord + "\\b.*");
// now contains == true; 

But with hashtag `contains` was false. Example:
text = "some text and #test word";
matchingWord = "#test"; 
contains = text.matches(".*\\b" + matchingWord + "\\b.*");
//contains == fasle; but I expect true    

【问题讨论】:

  • 那么,你需要匹配什么作为词边界呢?字符串或空格的开头?通常,您可以使用(?<!\\S) 作为初始边界,在这种情况下使用(?!\\S) 作为结尾边界(text.matches(".*(?<!\\S)" + matchingWord + "(?!\\S).*");)。
  • 另一种确保搜索词不在单词字符内的常用解决方案是使用明确的单词边界:text.matches(".*(?<!\\w)" + matchingWord + "(?!\\w).*")
  • 您可以简单地使用text.contains("#test") 结果将是true,如果您有一些特殊情况或多种情况,请使用regex
  • @PavneetSingh:如果文本中有#testing,那也会返回true
  • @WiktorStribiżew 是的,没错,我打算在之前的评论中给 OP 一些建议

标签: java android regex text


【解决方案1】:

\b# 模式匹配前面带有单词字符的#:字母、数字或下划线。

如果您需要匹配前面没有字符字符的#,请在(?<!\w) 后面使用否定的lookbehind。同样,如果存在非单词字符,要确保尾随 \b 匹配,请使用 (?!\w) 否定前瞻:

text.matches("(?s).*(?<!\\w)" + matchingWord + "(?!\\w).*");

如果您的matchingWord 可以包含特殊的正则表达式元字符,则使用Pattern.quote(matchingWord) 是一个好主意。

或者,如果您打算在空格或字符串的开头/结尾之间匹配搜索词,您可以使用 (?&lt;!\S) 作为初始边界,(?!\S) 作为尾随

text.matches("(?s).*(?<!\\S)" + matchingWord + "(?!\\S).*");

还有一件事:.matches 中的.* 并不是最好的正则表达式解决方案。像 "(?&lt;!\\S)" + matchingWord + "(?!\\S)"Matcher#find() 这样的正则表达式将以更加优化的方式进行处理,但您需要为此初始化 Matcher 对象。

【讨论】:

  • 这项工作,谢谢。但有一件事。如果在文本中匹配单词后我有换行符,则匹配器返回 false。例如"test #test\ntest"。你能改进这个正则表达式吗?
  • 添加(?s)。但如果你使用Matcher#find(),你甚至不需要它。
【解决方案2】:

如果您要查找带有前导“#”的词,只需从搜索词中删除前导“#”并使用以下正则表达式。

text.matches("#\\b" + matchingWordWithoutLeadingHash + "\\b");

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-04-01
    • 2023-03-26
    • 1970-01-01
    • 2014-10-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多