【问题标题】:Regex first character not matching正则表达式第一个字符不匹配
【发布时间】:2016-04-13 08:58:58
【问题描述】:

我遇到了一些 Java 模式问题。这是我的模式:

"^[\\p{L}\\p{Digit}~._-]+$"

它匹配任何 US-ASCII 字母、数字、一些特殊字符,基本上是任何不会打乱 URL 的东西。

我想要的是找到与此模式不匹配的单词中的第一个字母。基本上用户发送一个文本作为输入,如果我发现一个非法字符,我必须验证它并抛出异常。

我尝试否定这种模式,但它无法正确编译。 find() 也帮不上什么忙。

合法的输入应该是hello,而?hello 不应该是,我的例外应该指出? 不正确。

我更喜欢使用 Java 的 Matcher、Pattern 或使用 util.regex 的东西的建议。这不是必需的,但单独检查字符串中的每个字符并不是解决方案。

编辑:我想出了一个更好的正则表达式来匹配未保留的 URI 字符

【问题讨论】:

  • !"?hello".subString(0,1).matches("^[\\p{L}\\p{Digit}.'-.'_]+$")?
  • 你能分享一些你想要做什么的代码吗?试图清理 GET/POST 参数?还是整个网址?
  • 为什么在单个字符类中使用 2 ' 和 .?此外,'-. 创建了一个范围(并匹配'()*+,-.),这是故意的吗?顺便说一句,试试if (str.matches("[^\\p{L}\\p{Digit}.'_-].*")) { /* Error! */ }
  • 感谢 Wiktor 的观察

标签: java regex find match


【解决方案1】:

试试这个:

^[\\p{L}\\p{Digit}.'-.'_]*([^\\p{L}\\p{Digit}.'-.'_]).*$

第一个不匹配的字符是组n°1

我在这里做了一些尝试:http://fiddle.re/gkkzm61

解释:

我否定了你的模式,所以我建立了这个:

[^\\p{L}\\p{Digit}.'-.'_]      [^...] means every character except for
^                       ^             the following ones.
|  your pattern inside  |

图案有 3 个部分:

^[\\p{L}\\p{Digit}.'-.'_]*

从第一个字符开始检查正则表达式,直到遇到不匹配的字符

([^\\p{L}\\p{Digit}.'-.'_]) 

捕获组内的非匹配字符(否定)

.*$

直到字符串结尾的任何字符。

希望对你有帮助

编辑:

正确的正则表达式应该是:

^[\\p{L}\\p{Digit}~._-]*([^\\p{L}\\p{Digit}~._-]).*$

同样的方法,我只是改变了第一部分和第二部分的内容。

我试过了,它似乎有效。

【讨论】:

  • 我将其称为可接受的答案,但我最初的正则表达式没有正常工作,所以我编辑了问题
  • 根据您的建议,经过我的编辑,我认为这应该是正确的否定匹配器:"^[\\p{L}\\p{Digit}~._-]*([^\\p{L}\\p{Digit}~._-]).*$"
【解决方案2】:

"^[\\p{L}\\p{Digit}.'-.'_]+$" 模式匹配包含在字符类中定义的 1+ 个字符的任何字符串。请注意,双重' 和. 是可疑的,您可能不知道'-. 创建了一个范围并匹配'()*+,-.。如果不是故意的,我想你的意思是使用.'_-。

要检查字符串是否以字符类中定义的字符以外的字符开头,可以否定字符类,并仅检查字符串中的第一个字符:

if (str.matches("[^\\p{L}\\p{Digit}.'_-].*")) {
   /* String starts with the disallowed character */ 
}

我还认为您可以将正则表达式缩短为 "(?U)[^\\w.'-].*"。无论如何,\\p{Digit} 可以替换为\\d。

【讨论】:

    【解决方案3】:

    试试这个找出第一个无效字符:

    Pattern negPattern = Pattern.compile(".*?([^\\p{L}^\\p{Digit}^.^'-.'^_]+).*");
    Matcher matcher = negPattern.matcher("hel?lo");
    if (matcher.matches())
    {
        System.out.println("'" + matcher.group(1).charAt(0) + "'");
    }
    

    【讨论】:

    • 感谢您的帮助,这个 java Matcher 的工作方式真的很不直观
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-12-17
    • 1970-01-01
    • 2019-12-13
    • 2017-02-09
    • 1970-01-01
    • 2012-09-17
    • 2011-12-04
    相关资源
    最近更新 更多