匹配一切,但数字正则表达式

时间:2015-07-13 15:08:06

标签: regex r

我希望有一个正则表达式匹配任何不正确的数学数字。下面的列表是一个示例列表作为正则表达式的输入:

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

6 个答案:

答案 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]+,它将匹配除数字之外的任何内容。

Regular expression visualization

Debuggex Demo

答案 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