【问题标题】:Regular expressions: find string without substring正则表达式:查找没有子字符串的字符串
【发布时间】:2012-08-08 17:18:16
【问题描述】:

我有一个大文本:

"Big piece of text. This sentence includes 'regexp' word. And this
sentence doesn't include that word"

我需要找到以 'this' 开头并以 'word' 结尾但 包含单词 ' 的子字符串>正则表达式'。

在这种情况下,字符串:“this sentence doesn't include that word”正是我想要接收的。

如何通过正则表达式做到这一点?

【问题讨论】:

  • 您的规则令人困惑,或者您的预期输出有误。为什么没有“和”,为什么没有“大段文字”。
  • @sjakubowski "子串以 'this' 开始,以 'word' 结束"
  • 此规则令人困惑但正确。我花了很多时间在谷歌上找东西,但一无所获。

标签: regex


【解决方案1】:

使用忽略大小写选项,以下应该可以工作:

\bthis\b(?:(?!\bregexp\b).)*?\bword\b

示例:http://www.rubular.com/r/g6tYcOy8IT

解释:

\bthis\b           # match the word 'this', \b is for word boundaries
(?:                # start group, repeated zero or more times, as few as possible
   (?!\bregexp\b)    # fail if 'regexp' can be matched (negative lookahead)
   .                 # match any single character
)*?                # end group
\bword\b           # match 'word'

每个单词周围的\b 确保您没有匹配子字符串,例如匹配“thistle”中的“this”或“wordy”中的“word”。

这通过检查起始词和结束词之间的每个字符来确保排除的词不会出现。

【讨论】:

  • 这正是我所需要的!谢谢!
  • +1 很好地解释了正则表达式和使用它的链接 - 我能够将它应用于类似的东西,并且如果没有解释就会挣扎。我厌倦了只给出一些代码而不说明它是如何工作的答案。
  • 你帮了我很多!谢谢!
【解决方案2】:

使用前瞻资产。

当你想检查一个字符串是否不包含另一个子字符串时,你可以这样写:

/^(?!.*substring)/

您还必须检查thisword 的行首和行尾:

/^this(?!.*substring).*word$/

这里的另一个问题是你不想找到字符串,你想找到句子(如果我理解你的任务的话)。

所以解决方案是这样的:

perl -e '
  local $/;
  $_=<>;
  while($_ =~ /(.*?[.])/g) { 
    $s=$1;
    print $s if $s =~ /^this(?!.*substring).*word[.]$/
  };'

使用示例:

$ cat 1.pl
local $/;
$_=<>;
while($_ =~ /(.*?[.])/g) {
    $s=$1;
    print $s if $s =~ /^\s*this(?!.*regexp).*word[.]/i;
};

$ cat 1.txt
This sentence has the "regexp" word. This sentence doesn't have the word. This sentence does have the "regexp" word again.

$ cat 1.txt | perl 1.pl 
 This sentence doesn't have the word.

【讨论】:

  • 单靠前瞻是行不通的;您需要使用嵌套的前瞻。后面的代码 sn-p 很难阅读(我不懂 Perl),没有任何解释。 ://
  • @DragonWraith:你在说什么?这个灵魂确实解决了这个任务。你可以自己试试。
  • 我尝试了发布的 RegEx,但它没有这样做。 (?! 将阻止它匹配子字符串出现在this 之后的任何情况(来自示例),即使子字符串出现在word 之后。根据 F.J 的回答使用嵌套的 (?:(?! 可以解决此问题。我没有可用的 Perl 来测试那个 sn-p,但是我没有通过查看它来学习任何东西,而且我 can 告诉它它不是 RegEx 解决方案,因为它似乎使用while 循环手动遍历字符串。问题标记为regex 而不是perl
  • @DragonWraith:“即使子字符串出现在单词之后。”它不能出现在单词之后,因为它是字符串的最后一部分
  • 哦,我现在理解混乱了。您将示例测试用例作为他想要解析的确切字符串。他的条件并没有说明这个词将永远是字符串的最后一部分,在他给出的例子中恰好是真的。如果您有字符串This sentence has the "regexp" word. This sentence doesn't have the word. This sentence does have the "regexp" word again.,您的代码将找不到任何结果。
猜你喜欢
  • 1970-01-01
  • 2017-07-04
  • 2016-05-16
  • 2012-05-12
  • 2011-10-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多