正则表达式:匹配文本段落中除特定短语外的所有内容

Posted

技术标签:

【中文标题】正则表达式:匹配文本段落中除特定短语外的所有内容【英文标题】:Regex: Match everything in text paragraph except specific phrases 【发布时间】:2018-07-05 12:19:55 【问题描述】:

我正在为 Google Docs 编写一个免费插件并处理文本段落。

我需要一个正则表达式来匹配除短语(即用空格分隔的多个单词)之外的所有内容。

例如,当搜索文本The quick brown fox jumped over the lazy dog 时,我想匹配除quick brownlazy 之外的所有内容,预期结果为The fox jumped over the dog

\b((?!(lazy)\b).)+ 这行得通;它匹配除lazy 之外的所有文本,我得到The quick brown fox jumped over the dog

\b((?!(quick brown|lazy)\b).)+ 这不起作用;它离开brown,当我应该得到The fox jumped over the dog时我得到The brown fox jumped over the dog

我已经在网上搜索了几个小时,但没有任何运气。正则表达式缺少一些东西,我不知道它是什么。

感谢阅读!

正则表达式示例:https://regex101.com/r/3HGiff/1 javascript 示例:https://jsfiddle.net/g85je2aj/16/

编辑/更新:我开发了另一个解决方案,但它依赖于积极的后视,只有 Chrome 支持。

((?<=(quick brown|lazy)+(?=[\s]))|^(?!(quick brown|lazy))).+?((?=(quick brown|lazy))|$)

正则表达式示例:https://regex101.com/r/3HGiff/3 Javascript 示例:https://jsfiddle.net/g85je2aj/19/

由于这只适用于 Chrome,我认为这不是一个真正的解决方案。关于如何修改该正则表达式以不使用后视的任何想法,或者这是不可能的?

【问题讨论】:

您拥有的正则表达式首先匹配每个单词边界,然后匹配任何字符,1+ 次出现,这不是某些序列的起点。它最多匹配word 中的w,或two 中的t,因此匹配onetwo 之后的下一个单词边界,并继续匹配下一个one 或@987654344 @. 感谢 Wiktor 的解释。不幸的是,我不认为我离答案更近了。 你很亲密。您不需要匹配任何文本,但需要匹配其他一些文本。只需分享一个示例测试用例,JS 中的一个 sn-p(使用 jsfiddle.net 或在问题中添加代码)并解释您需要得到什么结果。 感谢 Wiktor,我在 regex101 和 jsfiddle 上都用更好的例子更新了这篇文章。 如果我是你,我会匹配给定的短语并使用replaceAll 删除它们 【参考方案1】:

您可以使用 拆分 方法,而不是匹配所有不匹配某些字符串的文本。您可以使用您需要避免构建基于替代的正则表达式的短语列表并将其与String#split() 一起使用:

var regExp = new RegExp("\\b(?:" + phrasesToSearchFor + ")\\b","i");
var results =  textToSearchIn.split(regExp);

您稍后需要做的就是访问results 数组中的所有项目。

这里是 JS 演示:

$(document).ready(function() 
  $("#button").click(function () 
  //the text to search for words in, then inverse highlight
  var textToSearchIn = "The quick brown fox jumped over the lazy dog.";
  //phrases to search for in a regex-friendly format
  //please note: this string vary in length and number of phrases 
  //  as it is parsed from an array of phrases using array.join('|');  
  var phrasesToSearchFor = "quick brown|lazy";
  //build a new regular expression to match everything but the phrasesToSearchFor
  //the best regex I have figured out is:  \b((?!(quick brown|lazy)\b).)+
  //but it only works for single-word phrases
  var regExp = new RegExp("\\b(?:" + phrasesToSearchFor + ")\\b","i");
  //do a while loop to collect all the matches
  var results =  textToSearchIn.split(regExp);
  for (var result of results) 
    //format the matche as a list item.  we only need the first group [0]
    var result = $('<li>' + result + '</li>');
    //send the match to the html list
    $('#output').before(result);
  
  /* expected output:  
     * The 
     * fox jumped over the 
     * dog.
    actual output:    
     * The 
     * brown fox jumped over the 
     * dog.
  */
  );
 );
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="button">Click to test</button>
<ul id="output"></ul>

【讨论】:

【参考方案2】:

或者您可以改用捕获组:

(.*)(one|two words)\s(.*)

然后,您可以通过使用:$1$3 来获取没有指定单词的文本。

示例: regex101.com

【讨论】:

嗨佩德罗 - 感谢您的想法!不幸的是,如果匹配多次出现,它就不起作用 - 例如sentence has foo and then foo again 它只会捕获foo 之一

以上是关于正则表达式:匹配文本段落中除特定短语外的所有内容的主要内容,如果未能解决你的问题,请参考以下文章

如何与正则表达式匹配PHP中除“-”之外的所有特殊字符?

正则表达式匹配引号外的所有单词?

正则表达式根据其中的值获取特定匹配括号后的所有内容

正则表达式匹配文本块与中间的关键短语

正则表达式,匹配特定字符后面的内容

求一段PHP的正则 我要匹配文本内所有的</h1>后的内容