java - Java 中的正则表达式没有按我的预期工作

标签 java regex

尝试提取用双括号括起来的字符串。例如应该匹配的 [[这是一个标记]]。为了使事情更优雅,应该有一个转义序列,以便像\[[this escaped token\]] 这样的双括号项目不会匹配。

模式 [^\\\\]([\\[]{2}.+[^\\\\][\\]]{2}) 与“组 1 ” 提取 token 很接近,但在某些情况下它不起作用。问题似乎是第一个“not”语句被评估为“除反斜杠之外的任何内容”。问题是,“任何事”并不包括“什么都没有”。那么,什么会使这个模式匹配“除了反斜杠之外的任何字符或任何字符”?

这是一个显示所需行为的单元测试:

import java.util.regex.Matcher;
import java.util.regex.Pattern;
import junit.framework.TestCase;

public class RegexSpike extends TestCase {
    private String regex;
    private Pattern pattern;
    private Matcher matcher;

    @Override
    protected void setUp() throws Exception {
        super.setUp();
        regex = "[^\\\\]([\\[]{2}.+[^\\\\][\\]]{2})";
        pattern = Pattern.compile(regex);
    }

    private String runRegex(String testString) {
        matcher = pattern.matcher(testString);
        return matcher.find() ? matcher.group(1) : "NOT FOUND";
    }

    public void testBeginsWithTag_Passes() {
        assertEquals("[[should work]]", runRegex("[[should work]]"));
    }

    public void testBeginsWithSpaces_Passes() {
        assertEquals("[[should work]]", runRegex("   [[should work]]"));
    }

    public void testBeginsWithChars_Passes() {
        assertEquals("[[should work]]", runRegex("anything here[[should
work]]"));
    }

    public void testEndsWithChars_Passes() {
        assertEquals("[[should work]]", runRegex("[[should
work]]with anything here"));
    }

    public void testBeginsAndEndsWithChars_Passes() {
        assertEquals("[[should work]]", runRegex("anything here[[should
work]]and anything here"));
    }

    public void testFirstBracketsEscaped_Fails() {
        assertEquals("NOT FOUND", runRegex("\\[[should NOT work]]"));
    }

    public void testSingleBrackets_Fails() {
        assertEquals("NOT FOUND", runRegex("[should NOT work]"));
    }

    public void testSecondBracketsEscaped_Fails() {
        assertEquals("NOT FOUND", runRegex("[[should NOT work\\]]"));
    }

}

最佳答案

您可以简单地使用 (^|[^\\]),它将或者匹配字符串的开头(前提是您设置了 MULTILINE<正则表达式上的/code> 模式)不是反斜杠的单个字符(包括空格、换行符等)。

您还需要将 .+ 替换为 .+?,因为否则会出现诸如 "[[one]] 和 [[two] 之类的字符串]]" 将被视为单个匹配,其中 "one]] 和 [[two" 被视为位于括号之间。

第三点是,您不必使用 \[\])包装在字符类中>[].

因此,这将生成以下正则表达式(请原谅我为了清楚起见删除了双重转义):

(^|[^\\])(\[{2}.+?[^\\]\]{2})

(另请注意,您无法使用正则表达式转义转义字符。[ 之前的两个斜杠不会被解析为单个(转义的)斜杠,但会指示单个 (未转义的)斜杠和转义的括号。)

关于java - Java 中的正则表达式没有按我的预期工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1045021/

相关文章:

java - 从集合中删除不符合条件的项目

java - websocket 连接可靠吗?

java - 如何使用 JavaExec 任务将 Java 代码嵌入到 Gradle 构建中

r - 计算字符串开头有多少个空格

java - 值未通过 Derby 数据库中的prepareStatement 插入

java - 使用 notnoop 的 java-apns 库时导致此错误的原因是什么?

regex - 正则表达式 - 在每个单词之前/之后添加一个字符

java - 如何查找字符串中的字符模式偏移量

r - 如何操作一列的两 block ?

c++ - 如何获取匹配组的索引