简体   繁体   English

Ruby Regex:否定先行,匹配前无限制

[英]Ruby Regex: negative lookahead with unlimited matching before

I'm trying to be able to match a phrase like: 我正在尝试匹配以下短语:

I request a single car
// or
I request a single person
// or
I request a single coconut tree

but not 但不是

I request a single car by id
// nor
I request a single person by id with friends
// nor
I request a single coconut tree by id with coconuts

Something like this works: 像这样的作品:

/^I request a single person(?!\s+by id.*)/

for strings like this: 对于这样的字符串:

I request a single person
I request a single person with friends

But when I replace the person with a matcher (.*) or add the $ to the end, it stops working: 但是,当我用匹配器(。*)替换此人或将$添加到末尾时,它将停止工作:

/^I request a single (.*)(?!\s+by id.*)$/

How can I accomplish this but still match in the first match everything before the negative lookahead? 我如何才能做到这一点,但仍然在否定超前前的所有比赛中匹配?

OK, I think I just got it. 好,我想我明白了。 Right after asking the question. 在问了问题之后。 Instead of a creating lookahead after the thing I want to capture, I create a lookahead before the thing I want to capture, like so: 我没有在要捕获的事物之后创建前瞻而是要捕获的事物之前创建了前瞻,如下所示:

/^I request a single (?!.*by id.*)(.*[^\s])?\s*$/

There's no ) to match ( in (.*\\) . Perhaps that's a typo, since you tested. After fixing that, however, there's still a problem: 没有( ) ((.*\\)匹配(.*\\)自您进行测试以来,这可能是拼写错误。但是,在解决此问题之后,仍然存在问题:

"I request a single car by idea" =~ /^I request a single (?!.*by id.*)(.*)$/
  #=> nil

Presumably, that should be a match. 大概应该是一个匹配。 If you only want to know if there's a match, you can use: 如果您只想知道是否有匹配项,可以使用:

r = /^I request a single (?!.+?by id\b)/

Then: 然后:

"I request a single car by idea" =~ r               #=> 0 
"I request a single person by id with friends" =~ r #=> nil

\\b matches a word break, which includes the case where the previous character is the last one in the string. \\b匹配一个分词符,其中包括前一个字符是字符串中的最后一个字符的情况。 Notice that if you are just checking for a match, there's no need to include anything beyond the negative lookahead. 请注意,如果您仅检查匹配项,则无需包含否定超前查询。

If you want to return whatever follows "single " when there's a match, use: 如果要在匹配时返回"single "后面的内容,请使用:

r = /^I request a single (?!.+?by id\b)(.*)/

"I request a single coconut tree"[r,1]              #=> "coconut tree"
"I request a single person by id with friends"[r,1] #=> nil

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM