Java:模式在扫描仪中的行为不同
Posted
技术标签:
【中文标题】Java:模式在扫描仪中的行为不同【英文标题】:Java: Pattern behaves differently in Scanner 【发布时间】:2017-12-09 03:37:04 【问题描述】:在 Java 中遇到了一个奇怪的正则表达式匹配行为。第一个输出命令按预期打印true
,但是当将相同的字符串打包到Scanner
中时,输出为false
。我做错了什么?
public static void main(String[] args)
Pattern p = Pattern.compile(" *\\[");
System.out.println(p.asPredicate().test("[]")); //true
Scanner s = new Scanner("[]");
System.out.println(s.hasNext(" *\\[")); //false
【问题讨论】:
试试s.hasNext(p)
@horcrux 来自 javadoc:此方法的调用形式为 hasNext(pattern) * 行为方式与调用完全相同 * hasNext (Pattern.compile(pattern)).
@SpaceTrucker 你是对的。所以重点是Pattern.compile(myRegex)p.asPredicate().test(myString)
在myString
中搜索myRegex
的出现,而new Scanner(myString).hasNext(myRegex)
检查myString
的全部内容是否与myRegex
匹配。
【参考方案1】:
来自public boolean hasNext(String pattern)
documentation:
如果下一个标记与从指定字符串构造的模式匹配,则返回 true。
这里的下一个标记是 []
不仅是 [
(因为分隔符是一个或多个空格)而且 " *\\["
模式与该标记不匹配完全(]
不匹配) 以便您通过结果false
了解它。
如果您想检查令牌是否以 [
开头,您可以在模式末尾添加 .*
以使其与令牌的其余部分匹配。您还可以删除 *
,因为空格是默认分隔符,因此它不能成为令牌的一部分。
万一
Pattern p = Pattern.compile(" *\\[");
System.out.println(p.asPredicate().test("a[]")); //true
如果您查看asPredicate
的代码,您会看到它的实现方式为:
public Predicate<String> asPredicate()
return s -> matcher(s).find();
find()
方法不会检查整个字符串是否与模式匹配,但会尝试找到与模式匹配的部分。由于[]
包含零个或多个空格,后跟[
,因此您看到的是true
。
【讨论】:
我明白了。是否有可能检查令牌的开始,或者我应该在每个正则表达式的末尾添加.*
?
这里最简单的方法是在末尾添加.*
。但是根据您真正想要实现的目标,最好避免使用 Scanner 并直接使用 Pattern ?不知道你真正想要达到的目标是很难说的。
我正在解析字符串,其中包含一个类似 JSON 的数组,所以我需要直接访问字符和解析整个 int 或 float 的简单方法。在这种情况下是否有任何替代扫描仪的方法。不能使用 JSON 解析器,这种情况不能通用处理。
@ViacheslavKroilov 如果没有看到真实数据和预期结果,我不能说太多。由于这个问题已经很少有关于当前描述的问题的答案,所以修改它是不好的,因为它会使发布的答案无效。因此,如果您想询问您的具体情况,请考虑创建单独的问题。【参考方案2】:
根据来自 Javadoc 的 Predicate.test
描述:
。如果输入参数与谓词匹配,则为 true,否则为 false
Javadoc 中没有明确写入但暗示test(T t)
方法与String.matches(String)
方法不匹配,其中开始和结束锚点是隐式的。另一方面,test
方法与完整字符串不匹配,您需要在正则表达式中使用锚点,使其行为类似于 String.matches
或 Scanner.hasNext(Pattern )
方法。
以下代码将在两个调用中给出一致的false
结果
final String input = "[]";
final String re = "^ *\\[$"; // note use of anchors in the regex
final Pattern p = Pattern.compile(re);
System.out.println(p.asPredicate().test(input)); // false
Scanner s = new Scanner(input);
System.out.println(s.hasNext(p)); //false
s.close();
【讨论】:
以上是关于Java:模式在扫描仪中的行为不同的主要内容,如果未能解决你的问题,请参考以下文章
扫描仪扫描文件处理-Photoshop批处理弹出色阶设置框解决