【问题标题】:Matching until first occurrence of a term followed by a character匹配直到第一次出现一个词后跟一个字符
【发布时间】:2017-05-09 12:54:21
【问题描述】:

我想匹配只有一个搜索词的字符串(在我的示例中这只是第一个字符串)。包含多个搜索词的字符串由+ 符号分隔:

  • jobs?search=term1&location=&distance=10+page=2

  • jobs?search=term1+term2&location=ca&distance=30

  • jobs?search=term1+term2+term3&location=nyc&distance=25

我的想法是匹配任何单词(前面是search=不是,然后是+,但,然后是&

search=.*?[^+]&

但它并不能很好地工作并捕获具有多个术语的字符串。

【问题讨论】:

  • 您能告诉我们它的编程语言是什么吗?
  • 我想在 Python 或 R 中使用它。
  • 哦,在 R 中它会有点笨拙,除非你想使用 stringr 包。然后我将添加示例代码。

标签: regex


【解决方案1】:

你需要使用

[&?]search=([^&+]+)(?=&|$)

regex demo

它将匹配:

  • [&?] - ?&(确保 search 是整个密钥名称)
  • search= - 文字子字符串
  • ([^&+]+) - 第 1 组捕获除 +& 之外的 1+ 个符号
  • (?=&|$) - 一个前瞻要求 & 或字符串结尾紧跟在前面的子模式捕获的最后一个符号之后(注意它可以替换为非捕获组,(?:&|$),该值仍将在第 1 组)。

Python demo:

import re
ss = ['jobs?search=term1&location=&distance=10+page=2','jobs?search=term1+term2&location=ca&distance=30','jobs?search=term1+term2+term3&location=nyc&distance=25']
rx = re.compile(r'[&?]search=([^&+]+)(?=&|$)')
for s in ss:
    m = rx.search(s)
    if m:
        print("{}: {}".format(s, m.group(1)))

Base R:

ss <- c('jobs?search=term1&location=&distance=10+page=2','jobs?search=term1+term2&location=ca&distance=30','jobs?search=term1+term2+term3&location=nyc&distance=25')
results <- regmatches(ss, regexec("[&?]search=([^&+]+)(?:&|$)",ss))
unlist(results)[2]

... 或与 R stringr:

> library(stringr)
> ss <- c('jobs?search=term1&location=&distance=10+page=2','jobs?search=term1+term2&location=ca&distance=30','jobs?search=term1+term2+term3&location=nyc&distance=25')
> results <- str_match(ss, "[&?]search=([^&+]+)(?:&|$)")
> results[,2]
[1] "term1" NA      NA     
> 

【讨论】:

  • 也许你应该删掉正则表达式开头的 [&?] 部分?
  • @Gawil:这里的“剪切”是什么意思?消除?但search 必须作为参数键匹配。我会保留它以便更安全地匹配。
  • @WiktorStribiżew:是的,我的意思是删除。我理解安全匹配......但OP不想要?匹配所以...也许有后视,取决于语言?
  • 任何涉及后视的解决方案都会降低性能。看看德甘特的回答。 370 stepsmy 213。我知道这并不能证明这里的性能差异很大,但仍然几乎是步骤的 2 倍。这也是因为他没有适当地使用惰性匹配。
  • 这就是为什么我确实建议削减 [&?] 而不是使用lookbehind(你只是想要一个安全的匹配)。我认为 OP 使用的字符串足够具体,不会在真正的关键字之前找到术语“search=”。
【解决方案2】:

如果您只想捕获术语而不是前面的search=

(?<=search=)[^+]*?(?=&|$)
  • (?&lt;=search=) - 正向向后查找以确保 search= 在术语之前
  • [^+]*? - 匹配术语(确保它不包含任何 +)。这是一个非贪婪匹配(使用*?),因此第一次出现 & 有效
  • (?=&amp;|$) - 正向预测以确保该术语后跟 &amp; 或字符串结尾 ($)

Regex101 Demo

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-25
    • 1970-01-01
    • 1970-01-01
    • 2013-03-26
    相关资源
    最近更新 更多