【问题标题】:How do I extract the fewest characters between two words?如何提取两个单词之间的最少字符?
【发布时间】:2013-08-04 05:42:43
【问题描述】:

我正在尝试在“我”和“不同意”这两个词之间找到最短的字符序列(不区分大小写)。我已经阅读了关于 SO 的所有类似问题,但似乎没有一个解决方案对我有用。这是一个让我伤心的例句:

作为一个美国人,我必须不同意你的观点。

这是我对正则表达式模式的最佳猜测:

我(.*?)不同意

我只想捕获 " 必须 ",但我要捕获更长的字符串," can, I must "。我希望不必指定“I”后面必须跟其他东西,比如空格。因为,那么我就不会在诸如“我不同意那个”之类的句子中捕捉任何内容。我也不想坚持“我”要大写。基本上,我只想要尽可能不贪婪的匹配。这个网站是我用来验证解决方案的地方之一:

http://regexpal.com/?flags=gi&regex=I%28.*%3F%29%20disagree&input=As%20an%20American%2C%20I%20must%20disagree%20with%20you。

【问题讨论】:

  • 使用\b 要求在捕获的部分周围有一个单词边界。然后收集所有匹配并选择最短的?
  • 这是一个实际用例吗?
  • 如果输入的是"I kinda disagree",你要" kinda ",还是"nda "
  • 一个我没想到的案例的优秀例子。我想看“有点”。尽管如此,我关心的并不是我寻找中间词的方法,而是我选择的方式并没有给出我预期的结果。我已经多次使用这种模式......我花了几个小时进行调试,然后才终于开始质疑我的正则表达式模式。我可能会使用边界建议这个词来解决实际问题,但负前瞻方法是我所期望的行为。
  • Gumbo,这是一个实际的用例。我是一名研究生,致力于自动将句子分类为表达同意或不同意。我正在寻找常用的最小词汇模式。

标签: javascript regex regex-greedy


【解决方案1】:

一般的做法是使用negative lookahead:

(I)(((?!\1).)*?) disagree

请在此处查看demo

注意中间单词的组现在是$2。如果你不想这样,你可以重复第一个词:

I((?:(?!I).)*?) disagree

但我想说第一个版本更容易维护,特别是如果单词是bigger

【讨论】:

  • 所有这些答案都非常有帮助。然而,这种消极的前瞻方法更准确地是我试图用我的正则表达式模式来完成的。
【解决方案2】:

你需要对正则表达式使用环视,使用这个正则表达式(?<=[iI])(\W.*)(?=disagree),你只会得到我和不同意之间的词。

Example here

【讨论】:

  • JavaScript 不支持后视断言。
  • 但我在 JEdit 中尝试了这个,这是可行的。我认为这些在 JDK 1.6 中已修复?
【解决方案3】:

使用单词边界 (\b):

/\bi(.*?)\bdisagree/i
  • 不区分大小写
  • 匹配I,但不匹配I'll'll 将成为捕获的一部分)

【讨论】:

  • 在 I 后面也放一个 \b,否则它将匹配任何以 I 开头的单词。\bI\b 将匹配 II'll 中的 I。跨度>
  • 单词边界只有在当然,它们之间的模式应该只是完整的单词时才有效。如果没有,字边界will not be general enough
  • 两者都是正确的,否则\s 将需要与一些正面/负面的lookbehinds一起使用
  • 它确实匹配I in I'll: See here
  • @Sumurai8:不,它仍然与I'll 中的I 匹配,'ll 将成为捕获内容的一部分;撇号' 将标记单词边界
猜你喜欢
  • 2020-12-30
  • 2011-11-30
  • 2012-04-13
  • 2020-06-16
  • 1970-01-01
  • 2014-05-28
  • 1970-01-01
  • 2013-12-12
  • 1970-01-01
相关资源
最近更新 更多