为了账号安全,请及时绑定邮箱和手机立即绑定

使用正则表达式在字符串中搜索子字符串

使用正则表达式在字符串中搜索子字符串

MMMHUHU 2022-12-28 14:16:01
我正在尝试搜索包含在ArrayList(terms_1pers)一个字符串中的一组单词,并且由于前提是搜索单词前后不应有字母,我想到了使用正则表达式。我只是不知道我在使用匹配运算符时做错了什么。在报告的代码中,如果未验证匹配,则写入外部文件。String url = csvRecord.get("url");String text = csvRecord.get("review");String var = null;for(String term : terms_1pers){   if(!text.matches("[^a-z]"+term+"[^a-z]"))   {      var="true";   }}if(!var.equals("true")){    bw.write(url+";"+text+"\n");}
查看完整描述

3 回答

?
幕布斯6054654

TA贡献1876条经验 获得超7个赞

为了找到正则表达式匹配项,您应该使用正则表达式类。模式和匹配器。


String term = "term";

ArrayList<String> a  = new ArrayList<String>();

a.add("123term456"); //true

a.add("A123Term5"); //false

a.add("term456"); //true

a.add("123term"); //true

Pattern p = Pattern.compile("^[^A-Za-z]*(" + term + ")[^A-Za-z]*$");

for(String text : a) {

    Matcher m = p.matcher(text);

    if (m.find()) {

         System.out.println("Found: " + m.group(1) );

         //since the term you are adding is the second matchable portion, you're looking for group(1)

    }

    else System.out.println("No match for: " + term);

}

}


在那里的示例中,我们创建了一个https://docs.oracle.com/javase/7/docs/api/java/util/regex/Pattern.html的实例,以在您匹配的文本中查找匹配项。


请注意,我稍微调整了正则表达式。此代码中的选择从初始匹配部分中排除了所有字母 AZ 和小写版本。它还将允许在匹配项之前或之后根本没有字符的情况。如果您需要在那里放置一些东西,请使用+而不是*. ^我还通过使用和$验证匹配文本的结尾来限制正则表达式以强制匹配仅包含这三个组的匹配项。如果这不适合您的用例,您可能需要进行调整。


为了演示如何使用各种不同的术语:


ArrayList<String> terms = new ArrayList<String>();

terms.add("term");

terms.add("the book is on the table");

terms.add("1981 was the best year ever!");

ArrayList<String> a  = new ArrayList<String>();

a.add("123term456");

a.add("A123Term5");

a.add("the book is on the table456");

a.add("1@#!231981 was the best year ever!9#");

for (String term: terms) {


    Pattern p = Pattern.compile("^[^A-Za-z]*(" + term + ")[^A-Za-z]*$");


    for(String text : a) {


        Matcher m = p.matcher(text);

        if (m.find()) {

             System.out.println("Found: " + m.group(1)  + " in " + text);

             //since the term you are adding is the second matchable portion, you're looking for group(1)

        }

        else System.out.println("No match for: " + term + " in " + text);

    }

}

此输出为:找到:123term456 中的术语不匹配:A123Term5 中的术语不匹配:书中的术语在 table456 上....


为了回答有关让字符串项不区分大小写的问题,这里有一种方法可以通过利用java.lang.Character大写和小写字母的选项来构建字符串。


String term = "This iS the teRm.";

String matchText = "123This is the term.";

StringBuilder str = new StringBuilder();

str.append("^[^A-Za-z]*(");

for (int i = 0; i < term.length(); i++) {

  char c = term.charAt(i);

  if (Character.isLetter(c))

    str.append("(" + Character.toLowerCase(c) + "|" + Character.toUpperCase(c) + ")");

  else str.append(c);

}

str.append(")[^A-Za-z]*$");


System.out.println(str.toString());



Pattern p = Pattern.compile(str.toString());

Matcher m = p.matcher(matchText);

if (m.find()) System.out.println("Found!");

else System.out.println("Not Found!");

此代码输出两行,第一行是在模式中编译的正则表达式字符串。"^[^A-Za-z]*((t|T)(h|H)(i|I)(s|S) (i|I)(s|S) (t|T)(h|H)(e|E) (t|T)(e|E)(r|R)(m|M).)[^A-Za-z]*$"这个调整后的正则表达式允许匹配术语中的字母而不考虑大小写。第二行输出是“Found!” 因为混合大小写术语在 matchText 中找到。


查看完整回答
反对 回复 2022-12-28
?
白板的微信

TA贡献1883条经验 获得超3个赞

有几点需要注意:

  • matches需要完整的字符串匹配,因此[^a-z]term[^a-z]只会匹配像:term.. 您需要使用.find()来查找部分匹配项

  • 如果将文字字符串传递给正则表达式,则需要Pattern.quote它,或者如果它包含特殊字符,则不会匹配

  • 要检查单词之前或之后在开始/结束时是否有某种模式,您应该使用带有锚点的交替(如(?:^|[^a-z])or (?:$|[^a-z]))或 lookarounds(?<![a-z])(?![a-z])

  • 要匹配任何字母,只需使用\p{Alpha}or - 如果您打算匹配任何 Unicode 字母 - \p{L}

  • var变量设置为布尔类型更符合逻辑。

固定代码:

String url = csvRecord.get("url");

String text = csvRecord.get("review");

Boolean var = false;

for(String term : terms_1pers)

{

   Matcher m = Pattern.compile("(?<!\\p{L})" + Pattern.quote(term) + "(?!\\p{L})").matcher(text);

   // If the search must be case insensitive use

   // Matcher m = Pattern.compile("(?i)(?<!\\p{L})" + Pattern.quote(term) + "(?!\\p{L})").matcher(text); 

   if(!m.find())

   {

       var = true;

   }

}

if (!var) {

   bw.write(url+";"+text+"\n");

}


查看完整回答
反对 回复 2022-12-28
?
慕田峪4524236

TA贡献1875条经验 获得超5个赞

您没有考虑开头和结尾可能包含字母的情况,因此在开头和结尾添加 .* 应该可以解决您的问题。


for(String term : terms_1pers)

{

   if( text.matches(".*[^a-zA-Z]+" + term + "[^a-zA-Z]+.*)" )  

   {

      var="true";

      break; //exit the loop

   }

}

if(!var.equals("true"))

{

    bw.write(url+";"+text+"\n");

}


查看完整回答
反对 回复 2022-12-28
  • 3 回答
  • 0 关注
  • 156 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信