[英]R gsub & regex find price
我正在尝试根据给定的文本创建新的价格向量。 我只被允许使用gsub
。
test = c('Testing $26,500\ntesting',
'Testing tesing $79+\n TOTAL: $79200',
'Testing $3880. Testing',
'Testing -$69000Engine: $69000100%',
'Testing testing original price : $ 8 2 9 5 . Real price is $ 7 4 9 5')
所需输出:
# [1] 26500 79200 3880 69000 7495
我尝试了多个正则表达式,但无法获得正确的结果。
第一次尝试:
gsub(".*\\$(\\d+)[,|.](\\d+).*", "\\1\\2", test)
# [1] "26500"
# [2] "Testing tesing $79+\n TOTAL: $79200"
# [3] "Testing $3880. Testing"
# [4] "Testing -$69000Engine: $69000100%"
# [5] "Testing testing original price : $ 8 2 9 5 . Real price is $ 7 4 9 5"
第二次尝试:
gsub(".*\\$(\\d+)[,|.].*", "\\1", test)
# [1] "26"
# [2] "Testing tesing $79+\n TOTAL: $79200"
# [3] "3880"
# [4] "Testing -$69000Engine: $69000100%"
# [5] "Testing testing original price : $ 8 2 9 5 . Real price is $ 7 4 9 5"
第三次尝试:
gsub("(?:.*|.*?*)\\$([0-9]+).*", "\\1", test)
# [1] "26"
# [2] "79200"
# [3] "3880"
# [4] "69000100"
# [5] "Testing testing original price : $ 8 2 9 5 . Real price is $ 7 4 9 5"
第四次尝试:
gsub(".*[-]\\$(\\d+).*", "\\1", test)
# [1] "Testing $26,500\ntesting"
# [2] "Testing tesing $79+\n TOTAL: $79200"
# [3] "Testing $3880. Testing"
# [4] "69000"
# [5] "Testing testing original price : $ 8 2 9 5 . Real price is $ 7 4 9 5"
问题 :如何解决此问题并避免使用多个gsub
函数调用?
我不相信有一种方法可以只对gsub
使用一次调用,因为您需要预处理最后一个价格(其中数字之间用空格“断开”,而第一个价格用逗号十进制分隔符)。
我只能将代码“压缩”到2个gsub调用中:
gsub("([$]|(?!^)\\\\G)[\\\\s,]*(\\\\d)", "\\\\1\\\\2", test, perl=T)
将删除逗号, $
符号后面的数字之间的空格 gsub("^(?|[\\\\s\\\\S]*-[$](\\\\d+)|[\\\\s\\\\S]*[$](\\\\d+))[\\\\s\\\\S]*$", "\\\\1", test, perl=T)
实际上会从字符串中获取所需的价格编号。 IDEONE演示 :
test <- c("Testing $26,500\ntesting","Testing tesing $79+\n TOTAL: $79200","Testing $3880. Testing", "Testing -$69000Engine: $69000100%","Testing testing original price : $ 8 2 9 5 . Real price is $ 7 4 9 5")
test <- gsub("([$]|(?!^)\\G)[\\s,]*(\\d)", "\\1\\2", test, perl=T)
test <- gsub("^(?|[\\s\\S]*-[$](\\d+)|[\\s\\S]*[$](\\d+))[\\s\\S]*$", "\\1", test, perl=T)
test
结果: [1] "26500" "79200" "3880" "69000" "7495"
由于您正在学习正则表达式,因此以下是正则表达式细分:
正则表达式1:
([$]|(?!^)\\\\G)
-匹配并捕获与$
符号匹配的“前导边界”构造,并在每次成功匹配后与(?!^)\\G
( \\G
也匹配开头的字符串,我们用负的前瞻(?!^)
消除它 [\\\\s,]*
-匹配0个或多个逗号或空格 (\\\\d)
-匹配并捕获一个数字 使用\\1\\2
替换模式,我们将$
符号及其后的数字还原到字符串中。
正则表达式2:
^
-字符串的开头 (?|[\\\\s\\\\S]*-[$](\\\\d+)|[\\\\s\\\\S]*[$](\\\\d+))
- 分支重置组 ( (?|...|...)
),其中捕获组索引被重置为1(因此,我们只需要在替换模式中使用\\1
引用来解决两个(\\\\d+)
来自每个替代项的匹配)。
[\\\\s\\\\S]*-[$](\\\\d+)
-任何零个或多个字符( [\\s\\S]*
),后跟一个连字符,再一个$
,再一个1个或多个数字( \\d+
,第1组) |
- 要么... [\\\\s\\\\S]*[$](\\\\d+)
-任何零个或多个字符( [\\s\\S]*
),后跟$
,然后是1个或多个数字( \\d+
, 仍为组1 ) 然后,我们仅用\\1
反向引用替换所有内容,以得到结果。 - [\\\\s\\\\S]*$
-任意字符,出现0次或更多( [\\s\\S]*
),直至字符串( $
)的末尾。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.