正则表达式中的通配符,仅在停用词之前是贪婪的 - java

我试图建立一个匹配以下语句的“简单”正则表达式(在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

在最佳情况下,它还应该匹配:
I want to cook something with candy and without nuts within 30 minutes

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

最好的情况下,我想写一个与此相似的模式:

I want to cook something ((with (?<include>.+))|((but )?without (?<exclude>.+))|(within (?<duration>.+) minutes))*

显然,这是行不通的,因为这些通配符也可以与关键字匹配,因此在第一个关键字匹配之后,其他所有内容(包括其他关键字)都将被相应命名捕获组的贪婪通配符匹配。

我尝试使用超前工作,例如这样的事情:

something ((with (?<IncludedIngredients>.*(?=but)))|(but )?without (?<ExcludedIngredients>.+))+

该正则表达式可识别something with chicken but without onions,但与something with chicken不匹配。

在正则表达式中是否有简单的解决方案?

附言“简单”解决方案意味着我不必在句子中指定这些关键字的所有可能组合,而不必按每种组合中使用的关键字数量对其进行排序。

参考方案

它可能可以归结为以下构造。

(?m)^I[ ]want[ ]to[ ]cook[ ]something(?=[ ]|$)(?<Order>(?:(?<with>\b(?:but[ ])?with[ ](?:(?!(?:\b(?:but[ ])?with(?:in|out)?\b)).)*)|(?<without>\b(?:but[ ])?without[ ](?:(?!(?:\b(?:but[ ])?with(?:in|out)?\b)).)*)|(?<time>\bwithin[ ](?<duration>.+)[ ]minutes[ ]?)|(?<unknown>(?:(?!(?:\b(?:but[ ])?with(?:in|out)?\b)).)+))*)$

https://regex101.com/r/RHfGnb/1

展开式

 (?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)
 $

java split regex-字符的任意组合 - java

我正在使用3个字符分割字符串:空格,破折号和逗号我想要的是能够使用这3个字符的任意组合进行拆分,例如:-,(破折号后跟逗号)或,--(逗号后加2破折号)或- , -(破折号,逗号间隔破折号)等 String address = "Sector -18B, Dwarka"; String[] addressParts = address.s…

Java:线程池如何将线程映射到可运行对象 - java

试图绕过Java并发问题,并且很难理解线程池,线程以及它们正在执行的可运行“任务”之间的关系。如果我创建一个有10个线程的线程池,那么我是否必须将相同的任务传递给池中的每个线程,或者池化的线程实际上只是与任务无关的“工人无人机”可用于执行任何任务?无论哪种方式,Executor / ExecutorService如何将正确的任务分配给正确的线程? 参考方案 …

JAVA:字节码和二进制有什么区别? - java

java字节代码(已编译的语言,也称为目标代码)与机器代码(当前计算机的本机代码)之间有什么区别?我读过一些书,他们将字节码称为二进制指令,但我不知道为什么。 参考方案 字节码是独立于平台的,在Windows中运行的编译器编译的字节码仍将在linux / unix / mac中运行。机器代码是特定于平台的,如果在Windows x86中编译,则它将仅在Win…

Java RegEx中的单词边界\ b - java

我在使用\b作为Java Regex中的单词定界符时遇到困难。对于text = "/* sql statement */ INSERT INTO someTable"; Pattern.compile("(?i)\binsert\b");找不到匹配项Pattern insPtrn = Pattern.compile(&…

java:继承 - java

有哪些替代继承的方法? java大神给出的解决方案 有效的Java:偏重于继承而不是继承。 (这实际上也来自“四人帮”)。他提出的理由是,如果扩展类未明确设计为继承,则继承会引起很多不正常的副作用。例如,对super.someMethod()的任何调用都可以引导您通过未知代码的意外路径。取而代之的是,持有对本来应该扩展的类的引用,然后委托给它。这是与Eric…