当前位置: 首页 > 面试题库 >

Java正则表达式交替运算符“ |” 行为似乎坏了

夹谷英奕
2023-03-14
问题内容

尝试为罗马数字编写正则表达式匹配器。在sed中(我认为这是正则表达式的“标准”吗?),如果您有多个由交替运算符分隔的选项,则它将与最长的匹配。即,"I|II|III|IV"将“
IV”匹配为“ IV”,将“ III”匹配为“ III”

在Java中,相同的模式将“ IV”的“ I”和“ III”的“ I”匹配。事实证明Java在从左到右的交替匹配之间进行选择;也就是说,因为正则表达式中的“
I”出现在“ III”之前,所以它匹配。如果我将regex更改为"IV|III|II|I",则行为会得到纠正,但这显然不是一般的解决方案。

有没有办法让Java从轮换组中选择最长的匹配项,而不是选择“第一个”?

为了清晰起见,代码示例:

public static void main(String[] args)
{
    Pattern p = Pattern.compile("six|sixty");
    Matcher m = p.matcher("The year was nineteen sixty five.");
    if (m.find())
    {
        System.out.println(m.group());
    }
    else
    {
        System.out.println("wtf?");
    }
}

这个输出 "six"


问题答案:

不,它的行为正确。Java使用NFA或正则表达式控制的风格,例如Perl,.NET,JavaScript等,
sed,grep或awk不同。预期一旦其中一项替代比赛结束,交替就退出,而不是最长的比赛坚持下去。

您可以通过在替换 之后 添加一个条件,直到消耗完整个令牌
,才能强制其继续运行。该条件可能取决于上下文;最简单的选择是锚点($)或单词边界(\b)。

"\\b(I|II|III|IV)\\b"

编辑:我应该提一下,尽管grep,sed,awk和其他 传统上
使用文本定向(或DFA)引擎,但是您也可以找到其中一些使用NFA引擎的版本,或者甚至是两者的混合版本。



 类似资料:
  • 问题内容: 这可能是一个愚蠢的问题,但我在任何地方都找不到: 如何在不带括号的情况下使用Java OR正则表达式运算符(|)? 例如:电话|电话|传真 问题答案: 您可以单独使用管道: 例如: 输出: 使用括号的主要原因是要限制替代方法的范围: 具有相同的输出。但是,如果您只是这样做: 你得到: 因为您说过“ string1”或“ 2”。 如果您不想捕获表达式的那一部分,请使用:

  • 本文向大家介绍Java正则表达式逻辑运算符,包括了Java正则表达式逻辑运算符的使用技巧和注意事项,需要的朋友参考一下 Java正则表达式支持3个逻辑运算符,它们是- XY:X,然后是Y X | Y:X或Y (X):捕获组。 XY:X,然后是Y 这仅匹配两个连续的单个字符。 示例 输出1 输出2 X | Y 这匹配“ |”周围的两个表达式/字符中的任何一个 示例 输出结果 (X):捕获组 捕获组使

  • 问题内容: 正则表达式中是否存在NOT运算符?就像在那个字符串中一样: 我想删除所有但不是一年的:。 因此,正则表达式应返回的内容必须是:。 注意:类似的东西对我不起作用(某种程度上也匹配…) 问题答案: 不,没有直接的非运算符。至少不是您希望的方式。 您可以使用零宽度的负前瞻,但是: 该部分的意思是“仅在 以下 文本(因此:前瞻)与此(因此:否定) 不 匹配时才匹配。但是它实际上并不会 消耗 其

  • 问题内容: 我有这个字符串: 现在,我想在每个数字之前添加String num:。 因此结果必须是: 这也必须工作: 用于搜索数字的正则表达式是:[0-9]+ 但是我想用num:+ [匹配的子字符串]替换匹配的子字符串。 我现在写了一个带有数字的示例,但另一个示例可以是:在每个电子邮件地址之前添加 ·Email found·: 问题答案: 利用分组。您可以使用括号(并)定义组,并通过组索引$n在哪

  • 正则表达式从左到右进行计算,并遵循优先级顺序,这与算术表达式非常类似。 相同优先级的从左到右进行运算,不同优先级的运算先高后低。下表从最高到最低说明了各种正则表达式运算符的优先级顺序: 运算符 描述 \ 转义符 (), (?:), (?=), [] 圆括号和方括号 *, +, ?, {n}, {n,}, {n,m} 限定符 ^, $, \任何元字符、任何字符 定位点和序列(即:位置和顺序) | 替

  • 此示例解释了两种形式的正则表达式运算符。 Match 它表示为〜。 它查找包含匹配字符串的字段。 例如,以下示例打印包含模式9 。 例子 (Example) [jerry]$ awk '$0 ~ 9' marks.txt 执行此代码时,您将获得以下结果 - 输出 (Output) 2) Rahul Maths 90 5) Hari History 89 不匹配 它表示为!~