Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/329.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 正则表达式中的通配符,只有在停止字之前才贪婪_Java_Regex_Regex Lookarounds_Capturing Group - Fatal编程技术网

Java 正则表达式中的通配符,只有在停止字之前才贪婪

Java 正则表达式中的通配符,只有在停止字之前才贪婪,java,regex,regex-lookarounds,capturing-group,Java,Regex,Regex Lookarounds,Capturing Group,我正在尝试构建一个“简单”的正则表达式(java)来匹配以下句子: I want to cook something I want to cook something with chicken and cheese I want to cook something with chicken but without onions I want to cook something without onions but with chicken and cheese I want to cook so

我正在尝试构建一个“简单”的正则表达式(java)来匹配以下句子:

I want to cook something
I want to cook something with chicken and cheese
I want to cook something with chicken but without onions
I want to cook something without onions but with chicken and cheese
I want to cook something with candy but without nuts within 30 minutes
在最佳情况下,它还应匹配:
我想在30分钟内做一些有糖没有坚果的东西

在这些例子中,我想捕捉“包括”成分、“排除”成分和烹饪过程的最大“持续时间”。正如您可以看到的那样,这3个捕获组中的每一个在模式中都是可选的,每个捕获组都以一个特定的单词(with,(but)?without,in)开始,并且组应该使用通配符进行匹配,直到找到下一个特定的关键字。此外,这些成分可能包含几个单词,因此在第二/第三个示例中,“鸡肉和奶酪”应与命名的捕获组“包含”匹配

在最好的情况下,我想写一个类似于此的模式:

I want to cook something ((with (?<include>.+))|((but )?without (?<exclude>.+))|(within (?<duration>.+) minutes))*
我想做点东西((用(?.+)|((但是)?不用(?.+)|(在(?.+)分钟内))*
显然,这不起作用,因为这些通配符也可以与关键字匹配,所以在第一个关键字匹配后,其他所有关键字(包括其他关键字)都将与相应命名捕获组的贪婪通配符匹配

我尝试过使用lookahead,例如:

something ((with (?<IncludedIngredients>.*(?=but)))|(but )?without (?<ExcludedIngredients>.+))+
something((带(?.*(=but))|(但是)?不带(?.+)+
该正则表达式识别带有鸡肉但没有洋葱的
东西,但与带有鸡肉的
东西不匹配

在正则表达式中有一个简单的解决方案吗


“简单”解决方案意味着我不必在一个句子中指定这些关键字的所有可能组合,并根据每个组合中使用的关键字数量对它们进行排序。

可能可以归结为以下结构

以下几种常用常用常用::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::)除了除了除了除了除了除了除除除除除除除除除除除除除除除除除除除除除除除除除除除除除除除除除除除除除除除除除除除其他之外之外之外之外之外之外,)之外,)之外,)之外,)之外,)之外,)除除除除除除除除)*)$

扩大

 (?m)
 ^ I [ ] want [ ] to [ ] cook [ ] something
 (?= [ ] | $ )
 (?<Order>                      # (1 start)
      (?:
           (?<with>                      # (2 start)
                \b
                (?: but [ ] )?
                with [ ]
                (?:
                     (?!
                          (?:
                               \b
                               (?: but [ ] )?
                               with
                               (?: in | out )?
                               \b
                          )
                     )
                     .
                )*
           )                             # (2 end)
        |  (?<without>                   # (3 start)
                \b
                (?: but [ ] )?
                without [ ]
                (?:
                     (?!
                          (?:
                               \b
                               (?: but [ ] )?
                               with
                               (?: in | out )?
                               \b
                          )
                     )
                     .
                )*
           )                             # (3 end)
        |  (?<time>                      # (4 start)
                \b within [ ]
                (?<duration> .+ )             # (5)
                [ ] minutes [ ]? 
           )                             # (4 end)
        |  (?<unknown>                   # (6 start)
                (?:
                     (?!
                          (?:
                               \b
                               (?: but [ ] )?
                               with
                               (?: in | out )?
                               \b
                          )
                     )
                     .
                )+
           )                             # (6 end)
      )*
 )                             # (1 end)
 $
(?m)
^我想做点什么
(?= [ ] | $ )
(?#(1开始)
(?:
(?#(2开始)
\b
(?:但是[])?
与[]
(?:
(?!
(?:
\b
(?:但是[])?
具有
(?:输入/输出)?
\b
)
)
.
)*
)#(二完)
|(?#(3开始)
\b
(?:但是[])?
没有[]
(?:
(?!
(?:
\b
(?:但是[])?
具有
(?:输入/输出)?
\b
)
)
.
)*
)#(三完)
|(?#(4开始)
\b在[]以内
(? .+ )             # (5)
[]分钟[]?
)#(四完)
|(?#(6开始)
(?:
(?!
(?:
\b
(?:但是[])?
具有
(?:输入/输出)?
\b
)
)
.
)+
)(六完)
)*
)#(一完)
$

您的模式不错。一旦你确定了量词的贪婪性质,就只考虑把它们变为不情愿的,即用<代码> > + >:< /P>取代<代码> ++/>代码>
String[] examples = {
    "I want to cook something",
    "I want to cook something with chicken and cheese",
    "I want to cook something with chicken but without onions",
    "I want to cook something without onions but with chicken and cheese",
    "I want to cook something with candy but without nuts within 30 minutes" };

Pattern p = Pattern.compile("I want to cook something"
    + "((( but)? with (?<include>.+?))|(( but)? without (?<exclude>.+?))"
        + "|( within (?<duration>.+?) minutes))*");

for(String s: examples) {
    Matcher m = p.matcher(s);
    if(m.matches()) {
        System.out.println(s);
        if(m.start("include") >= 0) System.out.println("\tinclude: "+m.group("include"));
        if(m.start("exclude") >= 0) System.out.println("\texclude: "+m.group("exclude"));
        if(m.start("duration") >= 0) System.out.println("\tduration: "+m.group("duration"));
    }
}

唯一需要更改的其他事项是,将可选的
添加到
,允许
不带…但带
,以及空格的位置,以匹配
“我想做点什么”
,不带尾随空格。

很难说清楚这是什么意思。在正则表达式中的下一个关键字出现之前,没有贪婪这样的东西<代码>abc.*(=abc)
不起作用。一些可行的方法是
(?:abc(?:(!abc)。*
我的建议是确保行以
开始,我想做一些
并将其从行中删除,然后拆分关键字(或正则表达式)上的剩余字符串。类似于
(?=带(?:in)|(?:but)?不带)
。然后提取您需要的内容。另一方面,@x15建议的方法是最好的方法,如果您试图采用一种主要是正则表达式的方法。在注释末尾创建的模式使用了一种被称为@x15的方法,贪婪的对立面是不情愿的。当您希望匹配在下一个关键字处停止时,您只是不希望贪婪。使用不情愿的量词比结合贪婪和消极前瞻要简单得多。不确定这是如何匹配那里的额外内容的。它是被迫匹配整行的吗?@x15在group1中,关于贪婪量词,PHP和Java之间似乎存在差异。似乎在PHP中,内部不情愿和o的组合uter贪心量词禁用回溯,而在java中则不禁用。我只在java中进行了测试。不幸的是,您链接的页面不提供“java风格”。测试是使第一个字符串
我想做一些ABC
如果它不匹配部分,