这项任务是在Codingbat上制定的。(https://codingbat.com/prob/p194491):
如果字符串中的每个“*”(星号),如果星号前后都有字符,则返回true。
sameStarChar("xy*yzz") → true
sameStarChar("xy*zzz") → false
sameStarChar("*xa*az") → true
如何修复我的解决方案,以便使用正则表达式解决此任务?
我的尝试:
public boolean sameStarChar(String str) {
return str.matches(".*([*])*.*");
}
我的解决方案对一半以上的测试都是正确的,但并非所有测试都是正确的。
它可以完成,但非常复杂。您的正则表达式只是扫描“任何东西,然后是任意数量的星星,然后是任何东西——这与所有内容都匹配。您的代码为几乎所有可以想象的字符串返回true
。
你的方法有问题。尝试积极匹配是相当复杂的。问题是否定的:“这个构造是无效的;任何没有无效构造的字符串都是有效的”,这就是问题的本质,无效的构造是:“A*B”,其中A和B不相同。毕竟,*a
是有效的(例3)。想必,***
也是有效的(第一颗星和最后一颗星没有问题,因为它们的两边都没有字符,中间的一颗星也可以,因为两边的字符都是相同的)。
因此,您需要编写一个正则表达式来查找无效构造,并返回逆。
要找到无效的构造,您需要一个称为反向引用的东西:您想要搜索一个东西,然后引用它。
“\*”
-我们从这里开始:一个角色、一颗星星和一个角色。但是现在我们需要第二个字符(第二个
实际上是:第一个字符以外的东西)。毕竟,
“\*”
也会在“A*A”
上匹配,这是一个有效的构造,所以我们不希望它匹配。
()
在regexese中创建一个'group'-您可以稍后参考的东西。\1
是一个backref-它是“与第一组括号匹配的任何内容”。
但我们需要更多——我们需要否定:如果不是这样,就匹配。在字符组中有
^
-[^fo]
的意思是:“任何不是'f'或'o'的字符”。但后卫并不是一个打手。
根据这个SO问题支持我的观点,唯一的方法是消极前瞻。前瞻是一种你实际上不匹配字符的东西,你只是检查它们是否匹配,如果匹配,匹配失败。这是...复杂。在网上搜索解释“积极前瞻”和“消极前瞻”的教程。
因此:
Pattern p = Pattern.compile("(.)\\*(?!\\1|$)");
return !p.matcher(str).find();
这里发生了各种各样的事情:
(?!X)
为负前瞻
\1 |$
的意思是:“第一组”或“字符串结束”。考虑到我们的输入包含X*
,该星号之后的下一个东西必须是X或字符串的结尾——如果是其他东西,我们应该返回false
我们不想匹配整个字符串。我们只想问:“无效构造”在这个字符串中的任何位置吗?-因此,find()
,而不是matches()
要明确的是,使用regexp来实现这一点可能是个坏主意。当然,代码会非常短,但不完全可读,是吗。
没有regexp,就更容易理解:
java prettyprint-override">for (int i = 1; i < str.length() -1; i++) {
if (str.charAt(i) != '*') continue;
if (str.charAt(i - 1) != str.charAt(i + 1)) return false;
}
return true;
我非常喜欢上面的regexp,而不是一个不容易显示它实际完成了什么的regexp,而且这个regexp肯定不能让仅仅通过查看它来理解它的功能。
我正在研究这个codingbat问题:如果字符串中的每个'*'(星形)都返回true,如果星形前后都有字符,那么它们是相同的。示例: 结果得到修正。我不明白我的第一次尝试有什么问题。
问题内容: 我正在测试 PHP 与 Java 。 爪哇 的PHP 除了不是由Java编码并由PHP转换为%2A的“星号”字符,所有这两个函数的字符似乎都以相同的方式编码。哪种行为应该是“正确的”行为(如果有)? 注意:我也尝试过-没有运气。 问题答案: 可以在URL中使用(但也可以采用编码形式)。 RFC1738:统一资源定位符(URL)声明以下内容: 保留: […] 通常,当八位字节由字符表示并
问题内容: 我想用字符替换Java字符串中的所有字符。因此,无论它是什么字符都无关紧要,应将其替换为。 我知道互联网上有很多例子,但是没有一个例子可以代替每个角色,我已经尽力了,但没有成功。 问题答案: Java 11及更高版本 注: 这将替换换行符用。如果要保留,请参见下面的解决方案。 Java 10及更早版本 这样可以 保留 换行符。 要在Java 10和更早的版本中也用换行符替换,可以使用:
问题内容: 在Java中,我想检查中是否存在字符串。 像这样: 问题是myList可以包含未修剪的数据: 如果我的项目在列表中,我希望它返回true 。我应该怎么做?我想避免循环结构。 问题答案: 您需要迭代列表并致电进行搜索: 或者,如果要执行 忽略大小写搜索 ,请使用:
问题内容: 例如,需要使用 字符串找出只读取字符串中 数字 的方法, 即 我的尝试 问题答案: 试试这个: 由于返回的是文本数组,因此您应该通过来访问第一个元素。
符号可以被视为运算符或负号。如果位于开始,则应将其视为负号和抹去字符串的减法。这仅适用于符号,而将始终是加号。如何实现此目的? 输入: 输出: 到目前为止我一直在尝试