如果有人帮我创建正则表达式以查找String中的所有*
和**
条目,我将非常感激。因为我不知道如何建立这个正则表达式。在字符串中,我们只能*
和.
例如:
*..***...**...****....*....*****..**
我们有4x *
和7x **
这就是我已经拥有的:
Pattern oneStarPattern = Pattern.compile("(^|\\.|(\\*{2})+)\\*(\\.|$)");
Pattern twoStarsPattern = Pattern.compile("(^|\\.|(\\*{2})+)\\*{2}(\\.|\\*|$)");
在输出中,我有5x *
和5x **
错误。
答案 0 :(得分:1)
在我解释你做错了什么以及如何纠正它之前,这是一个非常简单的方法,你可以用一个正则表达式来解决你的问题。想法是让正则表达式尝试匹配第一个**
,如果这不可能,那么尝试仅匹配*
。这样的正则表达式看起来像
\\*\\*|\\*
因为匹配器从左到右测试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})+)\\*(\\.|$)
只接受一个{/ 1}}
*
^
.
之前,
*
.
之后。
接受$
的策略,只要它有*
个偶数*
,.
或$
之后有一个缺陷,因为以防万一
****.
^^^^
标有^
的部分也将匹配(但不应该匹配)。
这就是为什么这个正则表达式匹配标有^
和#
标记#
的数据的原因不应该在那里:
*..***...**...****....*....*****..**
^^ ^^^^ #### ^^^ ^^^^^^
您看到5
次匹配。
另一个可能的问题是你的正则表达式会消耗周围的元素,因此在下次尝试查找下一个匹配时不能重用它们,所以在
的情况下*.*.
^^
第一个*.
将匹配,但.
将包含在此匹配中,这会阻止正则表达式在测试第二个*.
时使用它。由于第二个*.
无法在其匹配中包含第一个.
(在之前的匹配中使用),因此正则表达式将不正确,因为*
没有^
,{{1} },或者在它之前免费使用(\\*{2})+)
。
所以实际上即使.
也不应该包含在匹配
.
要解决这些问题,您可以使用look-around机制并将正则表达式更改为
*..***...**...****....*....*****..**
^# ^^^# #### #^# ^^^^^#
这个正则表达式会找到
"(?<=^|\\.)(\\*{2})*\\*(?=\\.|$)"
(*
)(\\*{2})*\\*
之前的.
(?<=^|\\.)
或其后的字符串结尾.
(?=\\.|$)
这个正则表达式与第一个类似的问题。让我们看看它目前匹配的是什么
(^|\\.|(\\*{2})+)\\*{2}(\\.|\\*|$)
每场比赛都有问题,因为
*..***...**...****....*....*****..**
^^^^ ^^^^ ^^^^ ^^^^ ^^^
.
,阻止了下一场比赛的使用*
将搜索最大可能偶数个星号(因为(^|\\.|(\\*{2})+)\\*{2}
),而不是一对这个正则表达式是过度复杂化事物的一个很好的例子。修复它似乎比第一个更难,但实际上它很简单
您只需要使用(\\*{2})+
正则表达式。它只匹配星号对,返回每个星号并寻找下一个星号。此正则表达式是安全的,因为您无法重复使用已匹配的\\*\\*
,因此它将匹配
**
其中*********
11223344x
1
2
3
表示在每次匹配迭代中返回的内容,与4
对应的*
不会完全匹配。