Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/328.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 Regexp:文本中的特定字符_Java_Regex - Fatal编程技术网

Java Regexp:文本中的特定字符

Java Regexp:文本中的特定字符,java,regex,Java,Regex,我的目标是验证某些文本中的特定字符(*,^,+,?,$,[],[^]),如: ?test.test => true test.test => false test^test => true test:test => false test-test$ => true test-test => false 我已经根据上面的要求创建了正则表达式,但我对此不确定 ^(.*)([\[\]\^\$\?\*\+])(.*)$ 很高兴知道是否可以用这种方式进行优化

我的目标是验证某些文本中的特定字符(*,^,+,?,$,[],[^]),如:

?test.test => true
test.test  => false

test^test => true
test:test => false

test-test$ => true
test-test  => false
我已经根据上面的要求创建了正则表达式,但我对此不确定

^(.*)([\[\]\^\$\?\*\+])(.*)$

很高兴知道是否可以用这种方式进行优化。

您的正则表达式已经进行了优化,因为它非常简单。您可以使其更简单或仅可读

另外,如果您使用Java的
String
类的
matches()
方法,则不需要在两端使用
^
$

.*([\\[\\]^$?*+]).*
Java使用双斜杠(
\\
),否则请使用单斜杠(
\

看,我已经删除了字符的捕获
()
以及转义字符
\
,因为它们位于字符类
[]

中,也应该可以工作:

String regex = ".*[\\[\\]^$?*+].*";

String test1 = "?test.test";
String test2 = "test.test";
String test3 = "test^test";
String test4 = "test:test";
String test5 = "test-test$";
String test6 = "test-test";

System.out.println(test1.matches(regex));
System.out.println(test2.matches(regex));
System.out.println(test3.matches(regex));
System.out.println(test4.matches(regex));
System.out.println(test5.matches(regex));
System.out.println(test6.matches(regex));
TL;DR

完成这项工作最快的正则表达式是

# ^[^\]\[^$?*+]*([\]\[^$?*+])

^               #start of the string
[^              #any character BUT...
    \]\[^$?*+   #...these ones (^$?*+ aren't special inside a character class)
]*+             #zero or more times (possessive quantifier)
([              #capture any of...
    \]\[^$?*+   #...these characters
])
注意,在java字符串中,还需要转义
\
,因此应该将每个
\
转换为
\

讨论

首先想到两个正则表达式:

  • [\]\[^$?*+]
    ,它将只匹配字符串中所需的字符
  • ^.*[\]\[^$?*+]
    ,这将使您的字符串与所需的字符匹配
从性能角度来看,理解开头有
*
的情况与根本没有通配符的情况之间的区别是非常重要的

搜索模式时,第一个
*
将使正则表达式引擎吃掉所有字符串,然后逐字符回溯,查看它是否与您的字符范围
[…]
匹配。因此正则表达式实际上将从字符串的末尾进行搜索

当你想要的标志接近尾声时,这是一个优势,当它在开始时,这是一个劣势

在另一种情况下,正则表达式引擎将尝试从左侧开始的每个字符,直到它与您想要的匹配为止

你可以从优秀的regex101.com网站上看到这两个例子的意思:

  • 使用
    *
    ,接近开始时在26个步骤中找到匹配项,接近开始时在8个步骤中找到匹配项:
  • 如果没有它,可以在5个步骤和23个步骤中找到它
现在,如果你想结合这两种方法,你可以使用tl;答:你吃了所有不属于你性格的东西,然后你就符合了你的性格(如果没有的话,你就会失败)


在上,无论字符在字符串中的什么位置,它都需要7个步骤(由于所有格量词,即使没有字符,也需要7个步骤)。

您不需要转义
^
$
*
+
哪个字符类。哪种编程语言?我已经指定了标记(java)。它不是为我编译的。那么我想在Java中,您确实必须避开
][
,这种行为有时取决于您使用的正则表达式的风格。@fashuser:Edited。这可能比您要求的要多一些,但正则表达式很有趣。谢谢大家的回答。
匹配()
查找()之间有区别吗在java中,除了添加的<代码> ^ $ < /C>之外,如果没有,你应该考虑使用<代码> FIN()/<代码>并去掉最后的<代码> */Cube >(第一个是我可以质疑的,看看我的答案,但是最后一个肯定没有任何用途)
String
类下的
方法。@SabujHassan:是的,似乎是一个方法。由于OP没有指定调用正则表达式的方式,可能与此有关。不过我不知道这两者之间的实现差异(字符串的匹配项和匹配器的查找)。@Robin
matches()
希望正则表达式与字符串完全相同。例如
\d
对于
xyz10abc
对于
matches()
返回false,但是对于
Matcher
将返回success。对于
Matcher()
您必须将正则表达式更改为
*\d+.