【问题标题】:How Can I Use Look-Ahead and Look-Behind to Create a Custom Boundary Matcher?如何使用 Look-Ahead 和 Look-Behind 创建自定义边界匹配器?
【发布时间】:2012-10-22 14:05:44
【问题描述】:

我想使用Scanner 在单词边界处拆分字符串。通常,这将是这样完成的:

Scanner scanner = new Scanner(...).useDelimiter("\\b");

问题是我对“单词”字符的定义与标准的[a-zA-Z_0-9] 有点不同,因为我想包含更多字符并排除_[a-zA-Z0-9#/]。因此,我不能使用\b 模式。

所以我尝试使用前瞻和后瞻来做同样的事情,但我想出的方法不起作用:

(<?=[A-Za-z0-9#/])(?![A-Za-z0-9#/])|(<?![A-Za-z0-9#/])(?=[A-Za-z0-9#/])

扫描仪不会使用这个分割任何地方。

是否可以使用前瞻和后视以及如何做到这一点?

【问题讨论】:

  • 只是一个小问题,但是您对\b 的“标准”定义也是错误的。
  • 我没有给出,但我认为它类似于(?&lt;=\w)(?!\w)|(?&lt;!\w)(?=\w)
  • 这就是 supposed 的定义方式,如果您使用 Java 7 及其新的UNICODE_CHARACTER_CLASS 模式,就是这样。但是 Java 的旧版 \b 更具...创造性。详情请参阅this question,尤其是@tchrist 的回答。

标签: java regex lookahead lookbehind


【解决方案1】:

您的语法有错误。 ? 先出现:

(?<=[A-Za-z0-9#/])(?![A-Za-z0-9#/])|(?<![A-Za-z0-9#/])(?=[A-Za-z0-9#/])
 ^^                                  ^^

【讨论】:

    【解决方案2】:
    new Scanner(...).useDelimiter(
      "(?<=[a-zA-Z0-9#/])(?=[^a-zA-Z0-9#/])|(?<=[^a-zA-Z0-9#/])(?=[a-zA-Z0-9#/])");
    

    【讨论】:

    • 不,这需要一个字符在前面和一个字符后面,所以它不会匹配字符串开头或结尾的单词边界。 OP 有正确的公式,他只是在语法上犯了一个小错误。
    • 他正在尝试为\b 创建一个符合他对单词字符定义的等价物。当与 Scanner 的 useDelimiter() 方法一起使用时,他更正的正则表达式与您的正则表达式完全相同 - 我承认,当我写评论时我没有意识到这一点。但我认为我的观点仍然有效:你的回答可能解决了他的问题,但并没有回答他的问题。
    • @AlanMoore - 再次阅读他的问题 - 它说:I want to split a string...
    • 好的,他应该问的问题。 :P 他自己的解决方案的问题在于语法,而不是语义。
    【解决方案3】:

    有什么问题:

    [^A-Za-z0-9#/]+
    

    换句话说,集合中至少有一个字符不是你的单词集的任何运行

    或者如果你需要空格

    [^A-Za-z0-9#/ ]+
    

    然后在扫描仪之后去除空格进行特殊处理(如果需要)

    【讨论】:

    • 我也需要单词之间的空格。扫描仪会使用您的正则表达式吞下它们。
    • 我认为 OP 希望将空格作为单独的“单词”/标记或我们称之为的任何东西 :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-01
    • 1970-01-01
    • 2011-02-06
    • 2012-04-30
    相关资源
    最近更新 更多