当前位置: 首页 > 面试题库 >

关于边界匹配器正则表达式(\ b)的以下代码段问题

鲜于谦
2023-03-14
问题内容

我的输入:

 1. end 
 2. end of the day or end of the week 
 3. endline
 4. something 
 5. "something" end

根据以上讨论,如果我尝试使用此代码段替换单个字符串,它将成功从行中删除适当的单词

public class DeleteTest {

    public static void main(String[] args) {

        // TODO Auto-generated method stub
        try {
        File file = new File("C:/Java samples/myfile.txt");
        File temp = File.createTempFile("myfile1", ".txt", file.getParentFile());
        String delete="end";
        BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(file)));
        PrintWriter writer = new PrintWriter(new OutputStreamWriter(new FileOutputStream(temp)));

        for (String line; (line = reader.readLine()) != null;) {
            line = line.replaceAll("\\b"+delete+"\\b", "");
       writer.println(line);
        }
        reader.close();
        writer.close();
        }
        catch (Exception e) {
            System.out.println("Something went Wrong");
        }
    }
}

我的输出如果我使用上面的代码段:(也是我的预期输出)

 1.  
 2. of the day or of the week
 3. endline
 4. something
 5. "something"

但是,当我包含更多要删除的单词时,并且为此目的,当我使用Set时,我将使用以下代码片段:

public static void main(String[] args) {

    // TODO Auto-generated method stub
    try {

    File file = new File("C:/Java samples/myfile.txt");
    File temp = File.createTempFile("myfile1", ".txt", file.getParentFile());
    BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(file)));
    PrintWriter writer = new PrintWriter(new OutputStreamWriter(new FileOutputStream(temp)));

        Set<String> toDelete = new HashSet<>();
        toDelete.add("end");
        toDelete.add("something");

    for (String line; (line = reader.readLine()) != null;) {
        line = line.replaceAll("\\b"+toDelete+"\\b", "");
    writer.println(line);
    }
    reader.close();
    writer.close();
    }
    catch (Exception e) {
        System.out.println("Something went Wrong");
    }
}

我得到的输出为:(它只是删除了空格)

 1. end
 2. endofthedayorendoftheweek
 3. endline
 4. something
 5. "something" end

你们可以帮我吗?


问题答案:

您需要创建一个 交替组 出一套用

String.join("|", toDelete)

并用作

line = line.replaceAll("\\b(?:"+String.join("|", toDelete)+")\\b", "");

图案看起来像

\b(?:end|something)\b

请参阅regex演示。在这里,(?:...)是一个 非捕获
组,用于对多个备用方案进行 分组, 而无需为捕获创建内存缓冲区(由于删除了匹配项,因此不需要它)。

或者,最好在进入循环之前编译正则表达式:

Pattern pat = Pattern.compile("\\b(?:" + String.join("|", toDelete) + ")\\b");
...
    line = pat.matcher(line).replaceAll("");

更新

要允许匹配包含特殊字符的整个“单词”,您需要使Pattern.quote这些单词转义那些特殊字符,然后需要使用明确的单词边界,(?<!\w)而不是使用首字母\b来确保之前没有单词char和(?!\w)否定的提前而不是决赛\b,以确保比赛结束后没有单词char。

在Java 8中,您可以使用以下代码:

Set<String> nToDel = new HashSet<>();
nToDel = toDelete.stream()
    .map(Pattern::quote)
    .collect(Collectors.toCollection(HashSet::new));
String pattern = "(?<!\\w)(?:" + String.join("|", nToDel) + ")(?!\\w)";

正则表达式看起来像(?<!\w)(?:\Q+end\E|\Qsomething-\E)(?!\w)。注意的符号\Q\E被解析
的文字符号



 类似资料:
  • 有没有人试图描述与正则表达式匹配的正则表达式? 由于重复的关键字,这个主题几乎不可能在网上找到。 它可能在实际应用程序中不可用,因为支持正则表达式的语言通常具有解析它们的方法,我们可以将其用于验证,以及一种在代码中分隔正则表达式的方法,可用于搜索目的。 但是我仍然想知道匹配所有正则表达式的正则表达式是什么样子的。应该可以写一个。

  • 我正在使用以下正则表达式: 我的目标是只验证数字(int和decimal),空格, ( ), 点,AND,OR。其他一切都是不允许的。它看起来像是工作的,但是我对单词边界\bAND\b和\bOR\b Eg有问题。我不能输入ANDWE或EEE或任何组合,但我能做的是AN或A。如何在字符串中只允许两个单词AND或OR?它们在字符串中是可选的。 输入示例 0.10和23-有效 12和(15或0.2)-有

  • 我们得到了一些这样的内容:

  • 本文向大家介绍常用正则表达式匹配代码介绍,包括了常用正则表达式匹配代码介绍的使用技巧和注意事项,需要的朋友参考一下 正则表达式,又称正规表示法、常规表示法。(英语:Regular Expression,在代码中常简写为regex、regexp或RE),计算机科学的一个概念。正则表达式使用单个字符串来描述、匹配一系列符合某个句法规则。在很多文本编辑器里,正则表达式通常被用来检索、替换那些符合某个模式

  • 主要内容:基本模式匹配,字符簇,确定重复出现基本模式匹配 一切从最基本的开始。模式,是正则表达式最基本的元素,它们是一组描述字符串特征的字符。模式可以很简单,由普通的字符串组成,也可以非常复杂,往往用特殊的字符表示一个范围内的字符、重复出现,或表示上下文。例如: 这个模式包含一个特殊的字符 ^,表示该模式只匹配那些以 once 开头的字符串。例如该模式与字符串 "once upon a time" 匹配,与 "There once was

  • 我无法在Android环境中设置RegEx匹配器。 我的字符串模式: 未转义的模式(匹配所有内容,但西里尔字母和拉丁字母,数字,空格,逗号,感叹号,减号,下划线,方括号,分号和加全局忽略大小写;我认为这些是“合法的”): 我的代码: 但是,这既不会引发任何错误,也不会起作用。 到目前为止,我尝试过但没有成功(其中string是String变量): < li> < Li > < code > pat