R-- 给字符串加前导零,没有固定的字符串格式
R-- Add leading zero to string, with no fixed string format
我有一列如下。
9453、55489、4588、18893、4457、2339、45489HQ、7833HQ
如果数字少于 5 位,我想添加前导零。但是,有些数字最后有"HQ",有些没有。(我检查了其他post,他们在"HQ"部分没有类似问题)
所以最终想要的输出应该是:
09453、55489、04588、18893、04457、02339、45489HQ、07833HQ
知道怎么做吗?非常感谢您阅读我的 post!
使用正则表达式的一行代码:
my_strings <- c("9453", "55489", "4588",
"18893", "4457", "2339", "45489HQ", "7833HQ")
gsub("^([0-9]{1,4})(HQ|$)", "0\1\2",my_strings)
[1] "09453" "55489" "04588" "18893"
"04457" "02339" "45489HQ" "07833HQ"
解释:
^ start of string
[0-9]{1,4} one to four numbers in a row
(HQ|$) the string "HQ" or the end of the string
圆括号按顺序表示捕获组。所以 0\1\2
表示 0
后跟第一个捕获组 [0-9]{1,4}
和第二个捕获组 HQ|$
。
当然如果有5个数字,那么正则表达式不匹配,所以它不会改变。
另一种尝试,在 "123"
或 "1HQR"
:
等情况下也有效
x <- c("18893","4457","45489HQ","7833HQ","123", "1HQR")
regmatches(x, regexpr("^\d+", x)) <- sprintf("%05d", as.numeric(sub("\D+$","",x)))
x
#[1] "18893" "04457" "45489HQ" "07833HQ" "00123" "00001HQR"
这基本上是在字符串 (^\d+
) 的开头找到任何数字,并用零填充(通过 sprintf
)字符串替换它们,该字符串通过删除任何非数字的子集字符串末尾的字符 (\D+$
)。
我打算使用 sprintf
方法,但发现 stringr
包提供了一个非常简单的解决方案。
library(stringr)
x <- c("9453", "55489", "4588", "18893", "4457", "2339", "45489HQ", "7833HQ")
[1] "9453" "55489" "4588" "18893" "4457" "2339" "45489HQ" "7833HQ"
这可以用一个简单的 stringr::str_pad()
函数转换:
stringr::str_pad(x, 5, side="left", pad="0")
[1] "09453" "55489" "04588" "18893" "04457" "02339" "45489HQ" "7833HQ"
如果即使字符串总宽度>5 也需要填充数字,则数字和文本需要用正则表达式分隔。
以下将起作用。它将正则表达式匹配与非常有用的 sprintf()
函数相结合:
sprintf("%05.0f%s", # this encodes the format and recombines the number with padding (%05.0f) with text(%s)
as.numeric(gsub("^(\d+).*", "\1", x)), #get the number
gsub("[[:digit:]]+([a-zA-Z]*)$", "\1", x)) #get just the text at the end
[1] "09453" "55489" "04588" "18893" "04457" "02339" "45489HQ" "07833HQ"
我们只能使用 sprintf()
和 gsub()
,方法是将这些部分分开然后重新组合起来。
sprintf("%05d%s", as.numeric(gsub("[^0-9]+", "", x)), gsub("[0-9]+", "", x))
# [1] "18893" "04457" "45489HQ" "07833HQ" "00123" "00001HQR"
使用@thelatemail 的数据:
x <- c("18893", "4457", "45489HQ", "7833HQ", "123", "1HQR")
我有一列如下。
9453、55489、4588、18893、4457、2339、45489HQ、7833HQ
如果数字少于 5 位,我想添加前导零。但是,有些数字最后有"HQ",有些没有。(我检查了其他post,他们在"HQ"部分没有类似问题)
所以最终想要的输出应该是:
09453、55489、04588、18893、04457、02339、45489HQ、07833HQ
知道怎么做吗?非常感谢您阅读我的 post!
使用正则表达式的一行代码:
my_strings <- c("9453", "55489", "4588",
"18893", "4457", "2339", "45489HQ", "7833HQ")
gsub("^([0-9]{1,4})(HQ|$)", "0\1\2",my_strings)
[1] "09453" "55489" "04588" "18893"
"04457" "02339" "45489HQ" "07833HQ"
解释:
^ start of string
[0-9]{1,4} one to four numbers in a row
(HQ|$) the string "HQ" or the end of the string
圆括号按顺序表示捕获组。所以 0\1\2
表示 0
后跟第一个捕获组 [0-9]{1,4}
和第二个捕获组 HQ|$
。
当然如果有5个数字,那么正则表达式不匹配,所以它不会改变。
另一种尝试,在 "123"
或 "1HQR"
:
x <- c("18893","4457","45489HQ","7833HQ","123", "1HQR")
regmatches(x, regexpr("^\d+", x)) <- sprintf("%05d", as.numeric(sub("\D+$","",x)))
x
#[1] "18893" "04457" "45489HQ" "07833HQ" "00123" "00001HQR"
这基本上是在字符串 (^\d+
) 的开头找到任何数字,并用零填充(通过 sprintf
)字符串替换它们,该字符串通过删除任何非数字的子集字符串末尾的字符 (\D+$
)。
我打算使用 sprintf
方法,但发现 stringr
包提供了一个非常简单的解决方案。
library(stringr)
x <- c("9453", "55489", "4588", "18893", "4457", "2339", "45489HQ", "7833HQ")
[1] "9453" "55489" "4588" "18893" "4457" "2339" "45489HQ" "7833HQ"
这可以用一个简单的 stringr::str_pad()
函数转换:
stringr::str_pad(x, 5, side="left", pad="0")
[1] "09453" "55489" "04588" "18893" "04457" "02339" "45489HQ" "7833HQ"
如果即使字符串总宽度>5 也需要填充数字,则数字和文本需要用正则表达式分隔。
以下将起作用。它将正则表达式匹配与非常有用的 sprintf()
函数相结合:
sprintf("%05.0f%s", # this encodes the format and recombines the number with padding (%05.0f) with text(%s)
as.numeric(gsub("^(\d+).*", "\1", x)), #get the number
gsub("[[:digit:]]+([a-zA-Z]*)$", "\1", x)) #get just the text at the end
[1] "09453" "55489" "04588" "18893" "04457" "02339" "45489HQ" "07833HQ"
我们只能使用 sprintf()
和 gsub()
,方法是将这些部分分开然后重新组合起来。
sprintf("%05d%s", as.numeric(gsub("[^0-9]+", "", x)), gsub("[0-9]+", "", x))
# [1] "18893" "04457" "45489HQ" "07833HQ" "00123" "00001HQR"
使用@thelatemail 的数据:
x <- c("18893", "4457", "45489HQ", "7833HQ", "123", "1HQR")