我希望有一个正则表达式匹配任何不正确的数学数字。下面的列表是一个示例列表作为正则表达式的输入:
1
1.7654
-2.5
2-
2.
m
2..3
2....233..6
2.2.8
2--5
6-4-9
所以前三个( Bold )不应该被选中,其余应该被选中。 这是another post的一个密切话题,但由于它的负面性质,它是不同的。
我正在使用R,但我猜任何正则表达式。 以下是上述帖子中的最佳镜头:
a <- c("1", "1.7654", "-2.5", "2-", "2.", "m", "2..3", "2....233..6", "2.2.8", "2--5", "6-4-9")
grep(pattern="(-?0[.]\\d+)|(-?[1-9]+\\d*([.]\\d+)?)|0$", x=a)
输出:
\[1\] 1 2 3 4 5 7 8 9 10 11
答案 0 :(得分:4)
您可以使用以下正则表达式:
^(?:((\d+(?=[^.]+|\.{2,})).)+|(\d\.){2,}).*|[^\d]+$
请参阅演示https://regex101.com/r/tZ3uH0/6
请注意,您的正则表达式引擎应该支持使用可变长度的前瞻。您需要使用multi-line
标记,并且如评论中所述,您可以使用perl=T
来激活R中的预览。 / p>
这个正则表达式包含2个与OR连接的部分。第一部分是:
(?:((\d+(?=[^.]+|\.{2,})).)+|(\d\.){2,}).*
将匹配除了点或2或更多点之外的任何数字组合的数字组合。其中整个数据位于可重复的捕获组内,而不是此组,您可以使用后跟的数字点2次或更多次(用于匹配某些字符串,如2.3.4.
)。
在第二部分我们有[^\d]+
,它将匹配除数字之外的任何内容。
答案 1 :(得分:2)
我认为这应该可以胜任:
re <- "^-?[0-9]+$|^-?[0-9]+\\.[0-9]+$"
R> a[!grepl(re, a)]
#[1] "2-" "2." "m" "2..3" "2....233..6" "2.2.8" "2--5"
#[8] "6-4-9"
答案 2 :(得分:2)
a[grep("^-?\\d*(\\.?\\d*)$", a, invert=T)]
来自@Frank的建议编辑。
速度测试
a <- rep(a, 1e4)
all.equal(a[is.na(as.numeric(a))], a[grep("^-?\\d+(\\.?\\d+)?$|^\\d+\\.$", a, invert=T)])
[1] TRUE
library(microbenchmark)
microbenchmark(dosc = a[is.na(as.numeric(a))],
plafort = a[grep("^-?\\d*(\\.?\\d*)$", a, invert=T)])
# Unit: milliseconds
# expr min lq mean median uq max neval
# dosc 27.83477 28.32346 28.69970 28.51254 28.76202 31.24695 100
# plafort 31.92118 32.14915 32.62036 32.33349 32.71107 35.12258 100
答案 3 :(得分:0)
解决方案here很好。您只需添加否定案例[ - ]并反转选择!
a <- c("1", "1.7654", "-2.5", "2-", "2.", "m", "2..3", "2....233..6", "2.2.8", "2--5", "6-4-9")
a[grep(pattern="(^[1-9]\\d*(\\.\\d+)?$)|(^[-][1-9]\\d*(\\.\\d+)?$)",invert=TRUE, x=a)]
[1] "2-" "2." "m" "2..3" "2....233..6"
[6] "2.2.8" "2--5" "6-4-9"
答案 4 :(得分:0)
试试这个:
a[!grepl("^\\-?\\d?\\.?\\d+$", a)]
答案 5 :(得分:0)
我喜欢as.numeric()的简单性。这是我的建议:
require(stringr)
a <- c("1", "1.7654", "-2.5", "2-", "2.", "m", "2..3", "2....233..6", "2.2.8", "2--5", "6-4-9")
a
a1 <- ifelse(str_sub(a, -1) == ".", "string filler", a)
a1
outvect <- is.na(as.numeric(a1))
outvect