【问题标题】:Pattern compile error模式编译错误
【发布时间】:2013-02-24 19:17:24
【问题描述】:

我创建了两个模式来编译 RegexBuddy 中的 ls -l 输出,但在 Android 模式中编译给了我一个错误。在 Java 7 中它编译得很好。

原始模式是

  1. (^[l,d,-][-,r,w,x]{9})[\t,\s]{1,}([[a-z_][a-z0-9_]{0,30}|[0-9]{1,})[\t,\s]{1,}([[a-z_][a-z0-9_]{0,30}|[0-9]{1,})[\t,\s]{1,}([0-9]{0,})[\t,\s]{1,}([0-9]{4}-[0-9]{1,2}-[0-9]{1,2}\s[0-9]{2}:[0-9]{2})[\t,\s]{1,}(.{1,})
  2. (^[l,d,-][-,r,w,x]{9})[\t,\s]{1,}[0-9]{1,}[\t,\s]{1,}([[a-z_][a-z0-9_]{0,30}|[0-9]{1,})[\t,\s]{1,}([[a-z_][a-z0-9_]{0,30}|[0-9]{1,})[\t,\s]{1,}([0-9]{0,})[\t,\s]{1,}(\w{3}\s[0-9]{1,2}[\t,\s]{1,}([0-9]{1,2}:[0-9]{2}|[0-9]{4}))[\t,\s]{1,}(.{1,})

第一个是为了匹配

-rwxr-xr-x  1 doctor users    399 2011-11-11 13:33 shot.s

-rwxr-xr-x  1 100 100    399 2011-11-11 13:33 file.txt

第二个是为了匹配

匹配

-rwxr-xr-x  1 doctor users    399 Nov 22  2011 shot.s

-rwxr-xr-x  1 100 100    399 Nov 22 13:33 shot.s

在代码中:

  1. private static final Pattern LS_L =
        Pattern.compile("(^[l,d,-][-,r,w,x]{9})[\\t,\\s]{1,}([[a-z_][a-z0-9_]{0,30}|[0-9]{1,})[\\t,\\s]{1,}([[a-z_][a-z0-9_]{0,30}|[0-9]{1,})[\\t,\\s]{1,}([0-9]{0,})[\\t,\\s]{1,}([0-9]{4}-[0-9]{1,2}-[0-9]{1,2}\\s[0-9]{2}:[0-9]{2})[\\t,\\s]{1,}(.{1,})");
    
  2. private static final Pattern LS_L_1 =
        Pattern.compile("(^[l,d,-][-,r,w,x]{9})[\\t,\\s]{1,}[0-9]{1,}[\\t,\\s]{1,}([[a-z_][a-z0-9_]{0,30}|[0-9]{1,})[\\t,\\s]{1,}([[a-z_][a-z0-9_]{0,30}|[0-9]{1,})[\\t,\\s]{1,}([0-9]{0,})[\\t,\\s]{1,}(\\w{3}\\s[0-9]{1,2}[\\t,\\s]{1,}([0-9]{1,2}:[0-9]{2}|[0-9]{4}))[\\t,\\s]{1,}(.{1,})");
    

第一个抛出

02-24 21:14:21.854: E/AndroidRuntime(3072): Caused by: java.util.regex.PatternSyntaxException: Missing closing bracket in character class near index 219:
02-24 21:14:21.854: E/AndroidRuntime(3072): (^[l,d,-][-,r,w,x]{9})[\t,\s]{1,}([[a-z_][a-z0-9_]{0,30}|[0-9]{1,})[\t,\s]{1,}([[a-z_][a-z0-9_]{0,30}|[0-9]{1,})[\t,\s]{1,}([0-9]{0,})[\t,\s]{1,}([0-9]{4}-[0-9]{1,2}-[0-9]{1,2}\s[0-9]{2}:[0-9]{2})[\t,\s]{1,}(.{1,})
02-24 21:14:21.854: E/AndroidRuntime(3072):                                                                                                                                                                                                                            ^
02-24 21:14:21.854: E/AndroidRuntime(3072):     at java.util.regex.Pattern.compileImpl(Native Method)
02-24 21:14:21.854: E/AndroidRuntime(3072):     at java.util.regex.Pattern.compile(Pattern.java:400)
02-24 21:14:21.854: E/AndroidRuntime(3072):     at java.util.regex.Pattern.<init>(Pattern.java:383)
02-24 21:14:21.854: E/AndroidRuntime(3072):     at java.util.regex.Pattern.compile(Pattern.java:374)

第二个给我

02-24 21:00:24.166: E/AndroidRuntime(1366): Caused by: java.util.regex.PatternSyntaxException: Missing closing bracket in character class near index 250:
02-24 21:00:24.166: E/AndroidRuntime(1366): (^[l,d,-][-,r,w,x]{9})[\t,\s]{1,}[0-9]{1,}[\t,\s]{1,}([[a-z_][a-z0-9_]{0,30}|[0-9]{1,})[\t,\s]{1,}([[a-z_][a-z0-9_]{0,30}|[0-9]{1,})[\t,\s]{1,}([0-9]{0,})[\t,\s]{1,}(\w{3}\s[0-9]{1,2}[\t,\s]{1,}([0-9]{1,2}:[0-9]{2}|[0-9]{4}))[\t,\s]{1,}(.{1,})

【问题讨论】:

  • 天哪。我认为编译器只是对任何不得不查看它的人表示同情。
  • 你想匹配什么......鉴于正则表达式我怀疑它可以完全在正则表达式中完成,除非你指定你实际尝试匹配的模式..
  • @Some1.Kill.The.DJ 我说我匹配的是 ls -l 输出。它可以而且必须用正则表达式来完成。它在 RegexBuddy 中完美运行。用输出示例更新了问题。

标签: java android regex


【解决方案1】:

对我来说,通过在 [[a-z_] 字符类中转义 [ 来消除错误 - 每个正则表达式中有两个。

 [\\[a-z_]

一些正则表达式实现不需要[ 在字符类中转义,但java 这样做是因为“字符类可能出现在其他字符类中”。请参阅 Character class subtractiondocs

顺便说一句,您可以通过用\\d 替换所有[0-9] 并从所有[\\t,\\s] 中删除\\t 来缩短您的正则表达式,因为\\s 也匹配制表符,并删除所有逗号你的角色类,例如[-,r,w,x] 应该是 [-rwx]

如果您不担心匹配不区分大小写,您可以将所有 [a-z0-9_] 替换为 \\w

编辑

再看一遍,似乎没有理由在字符类中包含[,所以[[a-z_] 应该只是[a-z_]

【讨论】:

  • +1 我的第一个想法是多次出现的无用 , 对于有点挑剔的正则表达式解析器来说可能是个问题。
  • 谢谢。 [[ 确实导致了问题。我使用 [0-9] 而不是 \\d 因为文档鼓励developer.android.com/reference/java/util/regex/Pattern.html
  • @DoctororDrive。感谢您的参考:“如果您的意思是 0-9,请使用 [0-9] 而不是 \d,它还包括 Gurmukhi 数字等等。” 我不知道其他数字会被包括在内。那个 Android 文档看起来不错。
【解决方案2】:

除了@Mike 所说的:

  1. 将 {1,} 替换为 +
  2. [a-z_][a-z0-9_]{0,30} 你会搭配什么?当然不是 UNIX 文件名,因为这更像是 [^\0/]+

【讨论】:

  • [a-z_][a-z0-9_]{0,30} 是 Unix 用户名或组名
  • 是的,但为什么是 {0,30}?我可以想象有一个用户u,但没有一个没有名字的用户。你可以在这里(\S+)。
  • [a-z_] 表示一个没有数字的字母,然后是零到 30 个允许有数字的字母 [a-z0-9_]{0,30}
  • 但它可以是一个数字,或者类似Müller
  • Unix 用户名不能是数字,因为它可以被视为 UID linuxquestions.org/questions/linux-newbie-8/…
猜你喜欢
  • 2016-11-15
  • 1970-01-01
  • 2014-08-20
  • 1970-01-01
  • 1970-01-01
  • 2017-09-19
  • 2016-05-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多