Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/75.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Regex 对word(R正则表达式)进行负前瞻的意外结果_Regex_R - Fatal编程技术网

Regex 对word(R正则表达式)进行负前瞻的意外结果

Regex 对word(R正则表达式)进行负前瞻的意外结果,regex,r,Regex,R,我试图为包含“狗”而不是“猫”的句子创建规则。我希望函数返回FALSE,因为字符串同时包含“dog”和“cat” 使用否定: grepl("cat.*[^dog]", "asdfasdfasdf cat adsfafds dog", perl=T) 使用负前瞻: grepl("cat.*(?!dog)", "asdfasdfasdf cat adsfafds dog", perl=T) 在stringr包中使用str_detect函数 require(stringr) str_detect(

我试图为包含“狗”而不是“猫”的句子创建规则。我希望函数返回FALSE,因为字符串同时包含“dog”和“cat”

使用否定:

grepl("cat.*[^dog]", "asdfasdfasdf cat adsfafds dog", perl=T)
使用负前瞻:

grepl("cat.*(?!dog)", "asdfasdfasdf cat adsfafds dog", perl=T)
在stringr包中使用str_detect函数

require(stringr)
str_detect("asdfasdfasdf cat adsfafds dog", "cat.*(?!dog|$)")

这三种方法都返回true

您可以使用此正则表达式查找包含cat但不包含dog的字符串:

^((cat((?!dog).)*)|(((?!dog).)*?cat((?!dog).)*)+)$
这是基于答案。它考虑到狗可以在猫之前或之后出现


所有解决方案的问题在于,
cat.*
会找到
cat
,然后
*
会吃掉所有东西,包括
s

还有,你忘了处理狗先于猫的情况


正如Druzion所指出的,char类不是解决问题的方法。

一个简单的解决方案是创建一个函数来检查:-

i) 如果字符串同时包含
cat
dog
,则返回FALSE

ii)否则,返回TRUE

R码


cat\u dog您意识到
cat.[^dog]
将在字符串
cat foobarbaz god
cat foobarbaz odg
上失败。原因是
[^]
将匹配除内部字符以外的任何字符,而不是任何单词,而是内部字符。因此,它们应该返回true。原因是,如果负前瞻匹配,则它们将为真。如果希望它们为假,只需删除负数并使其成为正常组。@Druzion,您的意思是
grepl(“cat.*(=dog)”,“asdfasdfasdfcat adsfafds dog”,perl=T)
?这只是返回true,因为它检查字符串中是否有cat后跟dog。否。这是一个积极的前瞻,它将检查狗是否存在。使用负前瞻:
cat.*(!dog)
。我知道你已经这样做了,我只是想指出为什么第一种方法不起作用。我只是注意到这条线有一些不适合我的目的。我用“狗”和“猫”作为特别的词来表达这个问题。然而,我当然需要这是动态的。事实是,如果字符串中既没有“dog”也没有“cat”,而是有其他术语,那么上面的脚本仍然会产生true。例如,“asdfadsf giraffe adsfa gorilla”将产生true,因为在字符串中找不到这些单词。@matsuo_basho好的,我误解了最后一部分。我假设如果没有猫和狗,那么它也会被接受。我真的很喜欢你的解决方案,因为它非常优雅。。。。。也许有一个修改仍然可以达到我的目的。@matsuo_basho很抱歉没有及时回复..更新了代码..不是最好的..但它可以做到..你可以说这也可以不用Regexth完成这是一条相当复杂的线,但似乎是为了我的特定目的。我现在正在剖析它。似乎只有您的解决方案的第二部分可以满足我们的需要:
grepl(^(((!dog)。*?cat((!dog)。*)+$,“dog cat asdfadsfad”,perl=T)
满足我们的需要为什么我们需要该行中的^and$锚。根据您提供的链接,这是为了确保整个输入是消费者的。如果没有锚,正则表达式将如何运行?@matsuo_basho尝试将其与有锚和无锚的猫狗进行匹配,您将看到<代码>:)
@matsuo_basho如果没有锚,它可以找到匹配的子字符串。您可以将其用于可视化。
cat_dog <- function(x) { if (length(grep("(?=.*cat)(?=.*dog)", x, perl = TRUE)) != 0) {return(FALSE)} else {return(TRUE)} }
cat_dog <- function(x) { if (length(grep("(?=.*dog)", x, perl = TRUE) != 0)) {if (length(grep("(?=.*cat)", x, perl = TRUE)) != 0) {return(FALSE)} else {return(TRUE)}} else {return(FALSE)}}