正则表达式以匹配来自多个链接的文本

时间:2019-08-13 15:27:30

标签: regex

如何提取包含特定单词的链接?

例如:

https://www.test.com/text/1@@@https://www.test.com/text/word/2@@@https://www.test.com/text/text/word/3@@@https://www.test.com/3/text@@@https://www.test.com/word/3/text/text

如何从正则表达式下面搜索“ 单词”?

((https:).*?(@@@))

结果应该是这样

https://www.test.com/text/ 单词 / 2

https://www.test.com/text/text/ 单词 / 3

https://www.test.com/ 单词 / 3 / text / text

4 个答案:

答案 0 :(得分:2)

让我们尝试构建这种正则表达式。首先,我们需要找到url的开头:

/(https?:\/\//

对于?个网址,我们在https之后添加http

然后我们需要查找@@@以外的任何文本,因此我们需要添加:

(?:(?!@@@).)*

这意味着-任意数量的字符都未以@@@开头。

我们还需要再次添加单词本身和先前的子表达式,因为单词可以被任何文本包围:

word(?:(?!@@@).)*

但是问题是最后一个子表达式将跳过@@@之前的最后一个字符,因此我们需要再添加一个东西来处理它:

.(?=@@@|$)

表示-任何字符后跟@@@或字符串结尾。最终表达式将如下所示:

/(https:\/\/(?:(?!@@@).)*word(?:(?!@@@).)*.(?=@@@|$))/g

但是我相信,最好只用@@@分割文本,然后再用String.prototype.includes检查所需的单词。

答案 1 :(得分:1)

上一个答案

您确定要查找此正则表达式:

https://www.test.com/(text/)*word/\d+(/text)*

这是在 JavaScript 上下文中使用它的方式(非常斜杠/被反斜杠\/转义):

var str = 'https://www.test.com/text/1@@@https://www.test.com/text/word/2@@@https://www.test.com/text/text/word/3@@@https://www.test.com/3/text@@@https://www.test.com/word/3/text/text'; 
var urls = str.match(/https:\/\/www.test.com\/(text\/)*word\/\d+(\/text)*/g);
console.log(urls);

在数组中,您将确切地得到所需的元素。

更新问题后更新答案并添加作者的评论

如果您需要从示例字符串中提取word,则必须使用一些更复杂的常规异常:

var str = 'https://www.test.com/text/1@@@https://www.test.com/text/word/2@@@https://www.test.com/text/text/word/3@@@https://www.test.com/3/text@@@https://www.test.com/word/3/text/text'; 
var urls = str.match(/(?<=\/)\w+(?=\/\d+\/\w)|(?<=(\w\/\w+\/))\w+(?=\/\d)/g);
console.log(urls);

说明

这里是正则表达式/(?<=(\w\/\w+\/))\w+(?=\/\d)|(?<=\/)\w+(?=\/\d+\/\w)/g,受/.../限制,并带有g标志,强制模式搜索出现。

正则表达式有两个选择...|...

第一个(?<=\/)\w+(?=\/\d+\/\w)捕获以下情况:搜索的单词直接位于斜杠(?<=\/)的后面,而数字(?=\/\d+\/\w)后面的其他单词之前。

  

https://www.test.com/word/3/text/text

第二个替代项(?<=(\w\/\w+\/))\w+(?=\/\d)捕获以下情况:单词在域(?<=(\w\/\w+\/))之后是其他单词(实际上是两个斜杠,由字母数字字符分隔),而搜索到的单词紧跟在斜杠之前,之后是单词数字(?=\/\d)

  

https://www.test.com/text/word/2

     

https://www.test.com/text/text/word/3

所有斜杠必须转义:\/

构造(?<=...)在正则表达式中表示后向,而(?=...)在正则表达式中表示 lookahead

注释1。上面的示例当前仅在Chrome浏览器中可以正常运行,例如that

  

(...)现在向后看是ECMAScript 2018规范的一部分。在撰写本文时(2018年末),谷歌的Chrome浏览器是唯一支持后向的流行JavaScript实现。因此,如果跨浏览器兼容性很重要,则不能在JavaScript中使用后向。

注释2。 Lookbehnd,即使正确解释,在大多数正则表达式引擎中也必须包含 fixed length 正则表达式,但我不这样做继续上面的示例,因为该示例仍然有效,并且适用于Google Chrome的JavaScript engineJGsoft engine.NET framework RegEx classes中使用的正则表达式引擎。

注释3。大量编程语言中使用的许多正则表达式引擎广泛支持lookbehind语法或其较差的\K替换。

例如,我使用过的有关正则表达式的更多说明可以找到here

答案 2 :(得分:1)

如果word必须是路径名的一部分,则可以将filterURL结合使用,并检查路径名的部分是否包含单词。

let str = 'https://www.test.com/text/1@@@https://www.test.com/text/word/2@@@https://www.test.com/text/text/word/3@@@https://www.test.com/3/text@@@https://www.test.com/word/3/text/text';
let filteredUrls = str.split("@@@")
  .filter(s =>
    new URL(s).pathname
    .split('/')
    .includes('word')
  );
console.log(filteredUrls);

如果仅想使用正则表达式并且支持possessive quantifiers(javascript标记已删除),则可以使用:

https?://[^@w]*(?:@(?!@@)|w(?!ord)|[^@w]*)++word.*?(?=@@@|$)

Regex demo

答案 3 :(得分:0)

您可以先除以purrr::map(.x = x, .f = purrr::compose(~.x[[1]], class)) [[1]] [1] "data.frame" [[2]] [1] "tbl_df" [[3]] [1] "character" ,然后检查每个元素中是否存在@@@

/word/