Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 我是否总是需要转义非“一”的字符串中的元字符;字面意义上的“;?_Java_Regex_String - Fatal编程技术网

Java 我是否总是需要转义非“一”的字符串中的元字符;字面意义上的“;?

Java 我是否总是需要转义非“一”的字符串中的元字符;字面意义上的“;?,java,regex,string,Java,Regex,String,在正则表达式处理期间,似乎拒绝使用包含字符{或}的字符串。我可以理解这些是保留字符,我需要对它们进行转义,因此如果我这样做: string.replaceAll("\\" + pattern); 这是可行的,其中模式是任何以{开头的字符串 问题:是否有办法避免已经包含此类元字符的字符串出现此类问题,以便自动处理?在我看来,这应该与在字符串文本中添加双引号与接受已经具有双引号的字符串作为输入相同 java.util.regex.Pattern.quote(java.lang.String) 转

在正则表达式处理期间,似乎拒绝使用包含字符
{
}
的字符串。我可以理解这些是保留字符,我需要对它们进行转义,因此如果我这样做:

string.replaceAll("\\" + pattern);
这是可行的,其中
模式
是任何以
{
开头的字符串

问题:是否有办法避免已经包含此类元字符的字符串出现此类问题,以便自动处理?在我看来,这应该与在字符串文本中添加双引号与接受已经具有双引号的字符串作为输入相同

java.util.regex.Pattern.quote(java.lang.String)
转义正则表达式使用的元字符。

使用:

为指定的
String
返回文本模式
String

此方法生成一个
字符串
,可用于创建一个
模式
,该模式将匹配字符串
s
,就像它是一个文字模式一样

输入序列中的元字符或转义序列没有特殊意义

参数:
s
-要进行文字化的字符串
返回:
文本字符串替换
自:
1.5

博士

  • 如果需要正则表达式语法,请使用
    replaceAll
    replaceFirst
  • 如果希望将
    目标/替换
    对视为文本,请使用
    替换
    (它还替换目标的所有出现次数)

大多数人对字符串类中替换方法的不幸命名感到困惑,这些方法是:

  • replaceAll(字符串,字符串)
  • replaceFirst(字符串,字符串)
  • replace(CharSequence,CharSequence)
  • 替换(字符,字符)
由于
replaceAll
方法明确声明它替换了所有可能的目标,人们认为
replace
方法不保证这种行为,因为它不包含
all
后缀。
但是这个假设是错误的。

这些方法之间的主要区别如下表所示:

╔═════════════════════╦═══════════════════════════════════════════════════════════════════╗
║                     ║                             replaced targets                      ║
║                     ╠════════════════════════════════════╦══════════════════════════════╣
║                     ║           ALL found                ║      ONLY FIRST found        ║
╠══════╦══════════════╬════════════════════════════════════╬══════════════════════════════╣
║      ║   supported  ║ replaceAll(String, String)         ║ replaceFirst(String, String) ║
║regex ╠══════════════╬════════════════════════════════════╬══════════════════════════════╣
║syntax║      not     ║ replace(CharSequence, CharSequence)║              \/              ║
║      ║   supported  ║ replace(char, char)                ║              /\              ║
╚══════╩══════════════╩════════════════════════════════════╩══════════════════════════════╝
现在,如果您不需要使用正则表达式语法,请使用不希望使用的方法,但它将
target
replacement
视为文本

因此,与其使用
replaceAll(regex,replacement)

使用
替换(文字,替换)


如您所见,有两个重载版本的
replace
。它们都适用于您,因为它们不支持正则表达式语法。它们之间的主要区别在于:

  • replace(char-target,char-replacement)
    只需创建新字符串,并用原始字符串中的字符或您决定作为替换的字符(取决于它是否等于目标字符)填充它

  • replace(CharSequence目标,CharSequence替换)
    本质上等同于
    replaceAll(Pattern.quote(target)、Matcher.quoteReplacement(replacement.toString())
    这意味着它与
    replaceAll
    相同,但(这意味着它在内部使用正则表达式引擎),但它会自动为我们转义
    target
    replacement
    中使用的正则表达式元字符


您不需要任何额外的代码,只需要
\Q
\E
结构,如中所述

例如,在以下代码中:

String foobar = "crazyPassword=f()ob@r{}+";
Pattern regex = Pattern.compile("\\Q" + foobar "\\E");
模式将被编译,foobar的特殊字符将不会被解释为正则表达式字符。请参阅演示


它唯一不匹配的地方是输入中包含文字的位置。
\E
。如果您也需要解决这个问题,请在注释中告诉我,我会编辑以添加它。

使用
replace
而不是
replaceAll
@Pshemo:它们的行为不同?阅读文档…有
replace(char,char)
replace(String,String)
这两个答案都应该适合你。如果其中任何一个答案对你有帮助,请接受它,指出正确的解决方案!@downvoter是否介意提及这个答案的错误,以便我可以改进它?很好的信息,如果我想深入学习java正则表达式,你会推荐我哪些材料?:)@Muhammad是到目前为止我发现的关于纯正则表达式及其大多数风格在不同语言中实现的最佳教程。Java正则表达式教程也不错,但您还应该阅读模式类的文档,其中包含许多关于Java中支持哪些正则表达式机制的信息。
String foobar = "crazyPassword=f()ob@r{}+";
Pattern regex = Pattern.compile("\\Q" + foobar "\\E");