当前位置: 首页 > 知识库问答 >
问题:

如果字符串中的每个“*”(星号),如果星号前后都有字符,则返回true

云默
2023-03-14

这项任务是在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(".*([*])*.*");
}

我的解决方案对一半以上的测试都是正确的,但并非所有测试都是正确的。

共有1个答案

令狐运珧
2023-03-14

它可以完成,但非常复杂。您的正则表达式只是扫描“任何东西,然后是任意数量的星星,然后是任何东西——这与所有内容都匹配。您的代码为几乎所有可以想象的字符串返回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 。我应该怎么做?我想避免循环结构。 问题答案: 您需要迭代列表并致电进行搜索: 或者,如果要执行 忽略大小写搜索 ,请使用:

  • 问题内容: 例如,需要使用 字符串找出只读取字符串中 数字 的方法, 即 我的尝试 问题答案: 试试这个: 由于返回的是文本数组,因此您应该通过来访问第一个元素。

  • 符号可以被视为运算符或负号。如果位于开始,则应将其视为负号和抹去字符串的减法。这仅适用于符号,而将始终是加号。如何实现此目的? 输入: 输出: 到目前为止我一直在尝试