我正在尝试根据给定的文本创建一个新的价格向量。我只被允许使用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
函数调用?
答案 0 :(得分:4)
我不相信有一种方法只能使用1次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)
实际上会从字符串中获得所需的价格编号。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)
- 匹配并捕获 a&#34;领先的边界&#34;构造匹配$
符号,并且每次成功匹配后的位置(?!^)\G
(\G
也匹配字符串的开头,我们用负面预测消除它{{1} })(?!^)
- 匹配0个或多个逗号或空格[\\s,]*
- 匹配并捕获数字使用(\\d)
替换模式,我们会在字符串中恢复\1\2
符号及其后面的数字。
正则表达式2:
$
- 字符串的开头^
- 一个分支重置组((?|[\\s\\S]*-[$](\\d+)|[\\s\\S]*[$](\\d+))
),其中捕获组索引重置为1(因此,我们只需要使用(?|...|...)
引用在替换模式中,以解决来自每个替代方案的\1
匹配....
(\\d+)
- 任意零个或多个字符([\\s\\S]*-[$](\\d+)
)后跟一个连字符,然后是[\s\S]*
,然后是一个或多个数字($
,第1组) \d+
- 或...... |
- 任意零个或多个字符([\\s\\S]*[$](\\d+)
)后跟一个[\s\S]*
,然后是一个或多个数字($
,仍为第1组强>)我们只用\d+
反向引用替换所有内容以获取结果。
- \1
- 任何字符,0次或更多次出现([\\s\\S]*$
),直到字符串末尾([\s\S]*
)。