Stata 将字符串分成几部分
Stata split string into parts
我有一个字符串变量 (col1
),我想 在第一次出现整数时拆分 ,即生成变量 part1
和 part2
.
col1 part1 part2
--------------------------------------------------
AufderScholle12 AufderScholle 12
Kˆnigsbr¸ckerPlatz3 Kˆnigsbr¸ckerPlatz 3
Hansastr0A Hansastr 0A
Flur:3 Flur: 3
我还不知道如何使用关于这个问题的各种文章中的正则表达式来实现它。
以下适用于您的示例数据,但请注意我必须在正则表达式定义中插入 "non-conventional" 字符,因为我看不到使用 Stata 的正则表达式实现来表达 "all but numbers" 的方法:
clear
set more off
*----- example data -----
input ///
str30 orig
"AufderScholle12"
"K^nigsbr¸ckerPlatz3"
"Hansastr0A"
"Flur:3"
end
list
*----- what you want -----
gen p1 = regexs(1) if(regexm(orig, "([\-\^\¸\:a-zA-Z]*)([0-9]?.*)"))
gen p2 = regexs(2) if(regexm(orig, "([\-\^\¸\:a-zA-Z]*)([0-9]?.*)"))
list
正则表达式专家可以在这里看一下 Stata 的实现(一个非常简单的):
http://www.stata.com/support/faqs/data-management/regular-expressions/
检查更好的方法。
根据 Stata 的 help regex
Regular expression syntax is based on Henry Spencer's NFA algorithm,
and this is nearly identical to the POSIX.2 standard.
我更有信心的解决方案是使用字符串函数:
clear
set more off
*----- example data -----
input ///
str30 orig
"AufderScholle12"
"K^nigsbr¸ckerPlatz3"
"Hansastr0A"
"Flur:3"
end
list
*----- what you want -----
forvalues i = 0/9 {
gen p_`i' = strpos(orig, "`i'")
replace p_`i' = . if p_`i' == 0
}
egen fpos = rowmin(p*)
gen p1 = substr(orig, 1, fpos-1)
gen p2 = substr(orig, fpos, .)
drop fpos p_*
list
这只是找到第一个数字字符出现的位置,并使用它从原始文本中挑出子字符串。
见help string functions
。
编辑
"all but numbers"的一种表达方式是[^0-9]*
,所以下面的结果和原来的一样:
gen p3 = regexs(1) if(regexm(orig, "([^0-9]*)([0-9]?.*)"))
gen p4 = regexs(2) if(regexm(orig, "([^0-9]*)([0-9]?.*)"))
这不是一个完整的答案,只是@Roberto Ferrer 的有用答案的脚注,不能很好地作为评论。
另一种查找第一个整数位置的方法,无需创建 10 个新变量然后启动 egen
:
gen posint = .
quietly forval i = 0/9 {
replace posint = min(posint, strpos(orig, "`i'"))
}
我有一个字符串变量 (col1
),我想 在第一次出现整数时拆分 ,即生成变量 part1
和 part2
.
col1 part1 part2
--------------------------------------------------
AufderScholle12 AufderScholle 12
Kˆnigsbr¸ckerPlatz3 Kˆnigsbr¸ckerPlatz 3
Hansastr0A Hansastr 0A
Flur:3 Flur: 3
我还不知道如何使用关于这个问题的各种文章中的正则表达式来实现它。
以下适用于您的示例数据,但请注意我必须在正则表达式定义中插入 "non-conventional" 字符,因为我看不到使用 Stata 的正则表达式实现来表达 "all but numbers" 的方法:
clear
set more off
*----- example data -----
input ///
str30 orig
"AufderScholle12"
"K^nigsbr¸ckerPlatz3"
"Hansastr0A"
"Flur:3"
end
list
*----- what you want -----
gen p1 = regexs(1) if(regexm(orig, "([\-\^\¸\:a-zA-Z]*)([0-9]?.*)"))
gen p2 = regexs(2) if(regexm(orig, "([\-\^\¸\:a-zA-Z]*)([0-9]?.*)"))
list
正则表达式专家可以在这里看一下 Stata 的实现(一个非常简单的):
http://www.stata.com/support/faqs/data-management/regular-expressions/
检查更好的方法。
根据 Stata 的 help regex
Regular expression syntax is based on Henry Spencer's NFA algorithm, and this is nearly identical to the POSIX.2 standard.
我更有信心的解决方案是使用字符串函数:
clear
set more off
*----- example data -----
input ///
str30 orig
"AufderScholle12"
"K^nigsbr¸ckerPlatz3"
"Hansastr0A"
"Flur:3"
end
list
*----- what you want -----
forvalues i = 0/9 {
gen p_`i' = strpos(orig, "`i'")
replace p_`i' = . if p_`i' == 0
}
egen fpos = rowmin(p*)
gen p1 = substr(orig, 1, fpos-1)
gen p2 = substr(orig, fpos, .)
drop fpos p_*
list
这只是找到第一个数字字符出现的位置,并使用它从原始文本中挑出子字符串。
见help string functions
。
编辑
"all but numbers"的一种表达方式是[^0-9]*
,所以下面的结果和原来的一样:
gen p3 = regexs(1) if(regexm(orig, "([^0-9]*)([0-9]?.*)"))
gen p4 = regexs(2) if(regexm(orig, "([^0-9]*)([0-9]?.*)"))
这不是一个完整的答案,只是@Roberto Ferrer 的有用答案的脚注,不能很好地作为评论。
另一种查找第一个整数位置的方法,无需创建 10 个新变量然后启动 egen
:
gen posint = .
quietly forval i = 0/9 {
replace posint = min(posint, strpos(orig, "`i'"))
}