[英]Need help to create regular expression in Java
如果有人能帮助我创建正则表达式以查找String中的所有*
和**
条目,我将非常感激。 因为我不知道如何构建此正则表达式。 在字符串中,我们只能有*
和.
例如此处: *..***...**...****....*....*****..**
我们有4倍*
和7倍**
这就是我已经拥有的:
Pattern oneStarPattern = Pattern.compile("(^|\\.|(\\*{2})+)\\*(\\.|$)");
Pattern twoStarsPattern = Pattern.compile("(^|\\.|(\\*{2})+)\\*{2}(\\.|\\*|$)");
在输出上我有5x *
和5x **
这是什么问题。
在我解释您做错了什么以及如何纠正它之前,这里是一种非常简单的方法,您只需一个正则表达式即可解决问题。 想法是让正则表达式首先尝试匹配**
,如果这不可能,则尝试仅匹配*
。 这样的正则表达式可以看起来像
\\*\\*|\\*
因为OR
匹配器测试选项从左到右,所以在诸如
***
匹配器将首先找到\\\\*\\\\*
匹配项,然后匹配成功,因此将消耗前两个星号**
***
^^
此匹配器前进之后,将再次尝试检查\\\\*\\\\*
可以在此处匹配,但是由于这次只有一个*
, \\\\*\\\\*
将不匹配,因此匹配器将尝试在正则表达式中测试另一个选项\\\\*
。 因此,这次匹配器将仅返回一个*
。
***
^
等等。
此类应用程序的代码如下所示
String data = "*..***...**...****....*....*****..**";
Pattern p = Pattern.compile("\\*\\*|\\*");
Matcher m = p.matcher(data);
int tmp1 = 0, tmp2 = 0;
while (m.find()) {
if (m.group().length() == 1)//found *
tmp1++;
else //found **
tmp2++;
}
System.out.println(tmp1);
System.out.println(tmp2);
输出:
4
7
现在,让我们专注于当前的正则表达式。
您的第一个正则表达式(^|\\\\.|(\\\\*{2})+)\\\\*(\\\\.|$)
只接受一个*
^
.
*
在此之前,以及
.
$
之后。
只要*
前面有*
偶数,就接受*
策略.
或$
在它有一个缺陷之后,因为
****.
^^^^
标有^
部分也将匹配(但不应匹配)。
这就是为什么此正则表达式匹配标有^
和#
数据(其中标有#
数据不应该存在)的原因:
*..***...**...****....*....*****..**
^^ ^^^^ #### ^^^ ^^^^^^
并且您看到5
匹配项。
另一个可能的问题是您的正则表达式会消耗周围的元素,因此在下次尝试查找下一个匹配项时将无法重用它们,因此在
*.*.
^^
首先*.
将被匹配,但是.
将包含在此匹配项中,以防止正则表达式在测试第二个*.
使用它*.
。 因为第二*.
不能包含first .
(在先前的比赛中使用)在其比赛正则表达式中是不正确的,因为*
没有^
, (\\\\*{2})+)
或可以自由使用.
在它之前。
所以甚至在现实中.
不应该包含在比赛中
*..***...**...****....*....*****..**
^# ^^^# #### #^# ^^^^^#
为了摆脱这些问题,您可以使用环顾四周机制并将您的正则表达式更改为类似
"(?<=^|\\.)(\\*{2})*\\*(?=\\.|$)"
这个正则表达式将发现
*
( (\\\\*{2})*\\\\*
)的奇数 .
在它之前(?<=^|\\\\.)
.
或后面的字符串结尾(?=\\\\.|$)
(^|\\.|(\\*{2})+)\\*{2}(\\.|\\*|$)
这个正则表达式与第一个有类似的问题。 让我们看看它当前匹配什么
*..***...**...****....*....*****..**
^^^^ ^^^^ ^^^^ ^^^^ ^^^
每次比赛都有问题,因为
.
*
,以防止下一场比赛使用它 (^|\\\\.|(\\\\*{2})+)\\\\*{2}
将搜索最大可能的星号偶数(因为(\\\\*{2})+
),而不是一对 这个正则表达式是过度复杂化的很好的例子。 似乎比第一个更难修复,但实际上它很简单。
您只需要使用\\\\*\\\\*
正则表达式即可。 它将仅匹配一对星号,返回它们中的每一个并寻找下一个。 此正则表达式很安全,因为您不能重复使用已经匹配的**
,所以它将匹配
*********
11223344x
其中1
2
3
4
表示将在每次匹配迭代中返回的内容,而与x
对应的*
将完全不匹配。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.