如何检查字符串是否为正则表达式

23

我有一个字符串,如何检查该字符串是否是正则表达式,或者包含正则表达式,还是普通字符串?


3
也许有正则表达式可以检查一个字符串是否是正则表达式。这是个有趣的问题!但我怀疑是否有一种方法能够涵盖所有可能性。 - Alp
一个有效的正则表达式被当作“普通”字符串是不可能的吗? - oliholz
我认为 OP 的意思是,假设他/她有 String s = "my string with \[.\] and another [^b]."; 那么他/她如何知道该字符串包含正则表达式?我是对的还是我是对的?哈哈 - Buhake Sindi
你的意思是检查一个字符串是否为有效的正则表达式吗? - Sam Holder
6个回答

25

你唯一可靠的检查方式是判断这个 String 是否是一个语法正确的正则表达式:

boolean isRegex;
try {
  Pattern.compile(input);
  isRegex = true;
} catch (PatternSyntaxException e) {
  isRegex = false;
}

需要注意的是,即使对于像Hello WorldI'm not a regex这样的字符串,由于它们在技术上是有效的正则表达式,因此这将导致结果为true

这将返回false的唯一情况是那些无效的正则表达式字符串,例如[未关闭的字符类(未关闭的组+


1
@hoipolloi:你所说的“Java转义字符”仅存在于字符串字面量中。当我有一个String对象时,它们不存在。因此,要么我有一个表示^\w+$String(可能是通过看起来像这样的String字面量"^\\w+$"),要么我会编译错误(通过编写看起来像这样的String字面量"^\w+$")。但是没有“具有错误Java转义字符”的String对象。这根本不可能。 - Joachim Sauer
1
@Saurabh:在这种情况下,有两个明智的解决方案:确定设置是否为正则表达式,并坚持使用它(即只允许使用正则表达式 只允许使用非正则表达式),或者提供一个额外的设置来切换字符串是否被解释为正则表达式。猜测对你没有帮助。 - Joachim Sauer
1
@Saurabh:不行! 没有办法读取用户的思想![^abc]是一个正则表达式吗?还是它是一个字面字符串,因为我想要搜索这个正则表达式? - Joachim Sauer
1
“ä”是一个正则表达式吗?“Something; or another”也是一个正则表达式?另外,你似乎发布的是JavaScript代码而不是Java代码。 - Joachim Sauer
2
@Saurabh:如果你有能力,那当然很好,但我同意@Sam的看法,并认为你只是推迟了真正的问题。 - Joachim Sauer
显示剩余14条评论

4

虽然这不是很美观,但它可以检测简单的正则表达式(需要注意的是,这些正则表达式必须是为Java设计的,即具有相应的反斜杠字符转义)。

public boolean isRegex(final String str) {
    try {
        java.util.regex.Pattern.compile(str);
        return true;
    } catch (java.util.regex.PatternSyntaxException e) {
        return false;
    }
}

我能否像过滤字符串中的所有正则表达式字符一样做些什么,如果结果字符串等于原始字符串,则该字符串是正常的。 - Saurabh Kumar

1

普通字符串和正则表达式之间没有区别。 正则表达式只是一个普通字符串,用作模式以匹配另一个字符串中的模式出现。

正如其他人指出的那样,字符串可能不是有效的正则表达式,但我认为这是您可以执行的唯一检查。 如果它有效,则无法知道它是正则表达式还是普通字符串,因为它将是正则表达式。

它只是一个普通字符串,由正则表达式引擎以特定方式解释。

例如,“blah”是一个正则表达式,它只会匹配另一个字符串中出现的“blah”字符串。

从这个角度看,您可以看到正则表达式不需要包含任何进行更高级模式匹配的“特殊字符”,它只会匹配模式中的字符串。


1
也许他的意思是一个有效的正则表达式? - Jeff Foster
@Jeff,也许是吧。如果是这样,希望他能编辑问题以表明这一点,然后我会删除答案,因为在那种情况下它没有太多意义。 - Sam Holder
我能否像过滤所有正则表达式字符一样从字符串中过滤,并且如果结果字符串等于原始字符串,则该字符串是正常的。 - Saurabh Kumar
你说的“正则表达式字符”是什么意思?所有字符都是正则表达式字符,但是在某些情况下,当字符串用作正则表达式模式时,有些字符对于正则表达式引擎具有特殊含义。 - Sam Holder

1
也许您可以尝试使用Apache的regexp包(http://jakarta.apache.org/regexp/)来编译该正则表达式,如果出现异常,则说明它不是一个有效的正则表达式,因此可以视为普通字符串。
boolean validRE = true;
try {
    RE re = new RE(stringToCheck);
} catch (RESyntaxException e) {
    validRE = false;
}

显然,用户输入了无效的正则表达式,而您将其处理为普通字符串。


我能否像过滤字符串中的所有正则表达式字符一样做些什么,如果结果字符串等于原始字符串,则该字符串是正常的。 - Saurabh Kumar

1

如果有人只想区分普通文本字符串和正则表达式:

static boolean hasSpecialRegexCharacters(String s){
    Pattern regexSpecialCharacters = Pattern
            .compile("[\\\\\\.\\[\\]\\{\\}\\(\\)\\<\\>\\*\\+\\-\\=\\!\\?
      \\^\\$\\|]");
     return regexSpecialCharacters.matcher(s).find();
}

-3
/**
 * If input string is a regex, matches will always return a false.
 */ 
public boolean isRegex(final String str) {   
    return str != null ? !str.matches(str) : false;
}

3
字符串 x 是一个有效的正则表达式,可以匹配其本身,所以你的代码无法正确工作。 - svick
2
x.* 匹配 x.*,因此我认为甚至无法区分常规字符串和带有正则表达式符号的字符串。 - bcampolo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接