为啥“hello\\s*world”与“hello world”不匹配?

Posted

技术标签:

【中文标题】为啥“hello\\\\s*world”与“hello world”不匹配?【英文标题】:Why does "hello\\s*world" not match "hello world"?为什么“hello\\s*world”与“hello world”不匹配? 【发布时间】:2011-09-12 16:17:45 【问题描述】:

为什么这段代码会抛出 InputMismatchException ?

Scanner scanner = new Scanner("hello world");
System.out.println(scanner.next("hello\\s*world"));

http://regexpal.com/ 中的相同正则表达式匹配(使用 \s 而不是 \\s)

【问题讨论】:

regexpal.com 测试 javascript 正则表达式,而不是 java 正则表达式。您可以尝试使用fileformat.info/tool/regex.htm 来测试java 正则表达式。 @Marcelo 我最喜欢的在线 Java 正则表达式测试器:regexplanet.com/simple @Matt 谢谢,我收藏了它,以备下次需要时使用。 【参考方案1】:

扫描器,与匹配器相反,内置了字符串的标记化,默认分隔符是空格。因此,在比赛开始之前,您的“hello world”将被标记为“hello”“world”。如果您在扫描到不在字符串中的内容之前更改了分隔符,那将是匹配的,例如:

Scanner scanner = new Scanner("hello world");
scanner.useDelimiter(":");
System.out.println(scanner.next("hello\\s*world"));

但对于您的情况,您似乎应该只使用Matcher

这是“按预期”使用扫描仪的示例:

   Scanner scanner = new Scanner("hello,world,goodnight,moon");
   scanner.useDelimiter(",");
   while (scanner.hasNext()) 
     System.out.println(scanner.next("\\w*"));
   

输出将是

hello
world
goodnight
moon

【讨论】:

如果字符串是 hello:world 那么呢?!您不应该对输入中的内容做出假设:S 这与向 Navin 说明为什么他的代码不起作用有什么关系?我说“这将是匹配如果:”而不是“这将是适合生产使用的严格正确的代码,如果:”输入显然被假定为“hello world”;) 您可以只设置一个空分隔符而不是 : “”的分隔符会将字符串标记为“h”“e”“l”“l”“o”等。我想可以使用一些任意不可打印的控制字符,但最终如果您正在使用扫描仪解析输入需要以某种方式受到限制。【参考方案2】:

扫描仪的默认分隔符是空格,因此扫描仪会看到两个元素 helloworld。并且 hello\s+world 与 hello 不匹配,因此会引发 NoSuchElement 异常。

【讨论】:

【参考方案3】:

这些输入有效:

"C:\Program Files\Java\jdk1.6.0_21\bin\java"  RegexTest hello\s+world "hello      world"
'hello      world' does match 'hello\s+world'

代码如下:

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class RegexTest 

    public static void main(String[] args) 

        if (args.length > 0) 
            Pattern pattern = Pattern.compile(args[0]);

            for (int i = 1; i < args.length; ++i) 
                Matcher matcher = pattern.matcher(args[i]);
                System.out.println("'" + args[i] + "' does " + (matcher.matches() ? "" : "not ") + "match '" + args[0]  +"'");
            
        
    


【讨论】:

【参考方案4】:

扫描器的构造函数采用一个可选模式,用于将输入序列拆分为标记。默认情况下,这是一个空白模式。

Scanner#next 返回下一个标记,如果它匹配给定的模式。换句话说,您传递给 #next 的模式默认情况下可能不包含空格。

您可以调用 #useDelimiter 为您的用例配置扫描器。

【讨论】:

【参考方案5】:

扫描器的默认分隔符为\\s+ 如果您只想匹配hello\\s*world,只需调用scanner.useDelimiter("hello\\s*world")),然后只需调用scanner.next();

Alternativeley,您可以致电scanner.useDelimiter('any (escaped) char that would not occur in your text ') 并使用scanner.next("hello\\s*world"))

附带说明,如果您希望它至少有 1 个空格,则您希望使用 + 而不是 *

【讨论】:

这不起作用。 "" 的分隔符标记为 h e l l o ' ' w o r l d. 我已经编辑过了 :) 你需要使用一些你输入中肯定没有的字符。请注意,某些字符是特殊的正则表达式字符,您需要对它们进行转义才能使用它们。我经常使用的安全字符是#

以上是关于为啥“hello\\s*world”与“hello world”不匹配?的主要内容,如果未能解决你的问题,请参考以下文章

(自兴人工智能)python字符串

格式化

Python 备忘

Python字符串格式化

Python——基本的方法

据廖雪峰python3教程----python学习第三天