0

我有一个任意长度的字符串类型列表,我需要确保列表中的每个字符串元素都是字母数字或数字,没有空格和特殊字符等- \ / _

接受的字符串示例包括:

J0hn-132ss/sda
Hdka349040r38yd
Hd(ersd)3r4y743-2\d3
123456789

不可接受的字符串示例包括:

Hello
Joe
King

等基本无话。

我目前正在使用stringInstance.matches("regex")但不太确定如何编写适当的表达式

if (str.matches("^[a-zA-Z0-9_/-\\|]*$")) return true; 
else return false;

true对于不符合我提到的格式的单词,此方法将始终返回。

我用英语寻找的正则表达式的描述类似于:
任何字符串,其中字符串包含来自 (a-zA-Z AND 0-9 AND special characters)
OR (0-9 AND Special characters)
OR (0-9)

编辑:我想出了以下有效的表达方式,但我觉得它可能很糟糕,因为它不清楚或复杂。

表达方式:

(([\\pL\\pN\\pP]+[\\pN]+|[\\pN]+[\\pL\\pN\\pP]+)|([\\pN]+[\\pP]*)|([\\pN]+))+

我用这个网站来帮助我:http: //xenon.stanford.edu/~xusch/regexp/analyzer.html
请注意,我对正则表达式还是新手

4

4 回答 4

11

警告:“从不”写AZ

所有类似A-Z0-9出现在 RFC 定义之外的范围实例实际上在 Unicode 中都是错误的。特别是,诸如此类的东西[A-Za-z]可怕的反模式:它们肯定会表明程序员对文本有一种穴居人的心态,这种心态几乎完全不适合千禧年的这一面。Unicode 模式适用于 ASCII,但 ASCII 模式在 Unicode 上会中断,有时会导致您面临安全违规行为。无论您使用的是 1970 年代数据还是现代 Unicode,始终编写模式的 Unicode 版本,因为这样在您实际使用真正的 Java 字符数据时不会搞砸。这就像你使用转向灯的方式,即使你“知道”你身后没有人,因为如果你错了,你不会伤​​害,反之,你肯定会这样做。习惯使用 7 个 Unicode 类别:

  1. \pL为字母。请注意如何\pL键入比 . 短得多[A-Za-z]
  2. \pN为数字。
  3. \pM用于与其他代码点结合的标记。
  4. \pS用于符号、标志和印记。:)
  5. \pP为标点符号。
  6. \pZ用于空格等分隔符(但不是控制字符)
  7. \pC对于其他不可见的格式和控制字符,包括未分配的代码点。

解决方案

如果你只想要一个模式,你想要

 ^[\pL\pN]+$

尽管在 Java 7 中你可以这样做:

 (?U)^\w+$

假设您不介意带有任意组合标记的下划线和字母。否则你必须写得很别扭:

 (?U)^[[:alpha:]\pN]+$

是 Java 7的(?U)新特性。它对应于 Pattern 类的UNICODE_CHARACTER_CLASSES编译标志。它将 POSIX 字符类[:alpha:]和简单的快捷方式\w切换为实际使用完整的 Java 字符集。通常,它们仅适用于 1970sish ASCII 集,这可能是一个安全漏洞。

没有办法让 Java 7 总是在不被告知的情况下使用其模式执行此操作,但是您可以编写一个前端函数来为您执行此操作。你只需要记住打电话给你的。

请注意,v1.7 之前的 Java 模式不能按照UTS#18 on Unicode 正则表达式所说的方式工作。正因为如此,如果您不使用新的 Unicode 标志,就会让自己面临各种错误、不合理之处和悖论。例如,\b\w+\b在 string 中的任何地方都找不到平凡和常见的模式匹配"élève",更不用说整个模式了。

因此,如果您在 1.7 之前的 Java 中使用模式,您需要非常小心,比任何人都小心得多。您不能使用任何 POSIX charclasses 或 charclass 快捷方式,包括\w\s\b,所有这些都会破坏除了石器时代的 ASCII 数据之外的任何东西。它们不能用于 Java 的本机字符集。

在 Java 7 中,它们可以——但只能使用正确的标志。

于 2011-08-24T14:06:37.343 回答
1

可以将所需正则表达式的描述重新定义为“包含至少一个数字”,以便后续工作/.*[\pN].*/。或者,如果您想将搜索限制为应使用的字母数字和标点符号/[\pL\pN\pP]*[\pN][\pL\pN\pP]*/。我已经在您的示例中对其进行了测试,并且效果很好。

您可以通过使用像这样的惰性量词来进一步优化您的正则表达式/.*?[\pN].*?/。这样,如果没有数字,它会更快地失败。

我想向你推荐一本关于正则表达式的好书:掌握正则表达式,它有一个很好的介绍,深入解释了正则表达式的工作原理,还有一章关于 Java 中的正则表达式。

于 2011-08-25T03:50:53.297 回答
0

看起来您只是想确保字符串中没有空格。如果是这样,您可以非常简单地这样做:

return str.indexOf(" ") == -1;

如果没有空格,这将返回 true(根据我对您的规则的理解有效),如果字符串中的任何地方有空格(无效),则返回 false。

于 2011-08-24T13:47:29.870 回答
0

这是一个部分答案,它包含 0-9 和特殊字符 OR 0-9。

^([\d]+|[\\/\-_]*)*$

这可以读为 ((1 or more digits) OR (0 or more special char \ / -'_')) 0 次或更多次。它需要一个数字,只接受数字,并且会拒绝只包含特殊字符的字符串。

我使用正则表达式测试器测试了几个字符串。

添加字母字符似乎很容易,但可能需要重复给定的正则表达式。

于 2011-08-24T18:44:44.327 回答