Ste*_*rdi 2 regex string stata
假设我有以下本地宏:
loc a = 12.000923
Run Code Online (Sandbox Code Playgroud)
我想获得第一个非零小数的小数位(4在本例中).
有很多方法可以实现这一目标.一种是a作为一个字符串处理并找到以下位置.:
loc a = 12.000923
loc b = strpos(string(`a'), ".")
di "`b'"
Run Code Online (Sandbox Code Playgroud)
从这里可以进一步循环小数并计数,因为我得到第一个非零元素.当然,这似乎不是一个非常优雅的方法.
你能建议一个更好的方法来解决这个问题吗?也许正则表达式?
您可以mata在一行中执行此操作,而无需使用正则表达式:
foreach x in 124.000923 65.020923 1.000022030 0.0090843 .00000425 {
mata: selectindex(tokens(tokens(st_local("x"), ".")[selectindex(tokens(st_local("x"), ".") :== ".") + 1], "0") :!= "0")[1]
}
4
2
5
3
6
Run Code Online (Sandbox Code Playgroud)
下面,您可以看到详细步骤:
. local x = 124.000823
. mata:
: /* Step 1: break Stata's local macro x in tokens using . as a parsing char */
: a = tokens(st_local("x"), ".")
: a
1 2 3
+----------------------------+
1 | 124 . 000823 |
+----------------------------+
: /* Step 2: tokenize the string in a[1,3] using 0 as a parsing char */
: b = tokens(a[3], "0")
: b
1 2 3 4
+-------------------------+
1 | 0 0 0 823 |
+-------------------------+
: /* Step 3: find which values are different from zero */
: c = b :!= "0"
: c
1 2 3 4
+-----------------+
1 | 0 0 0 1 |
+-----------------+
: /* Step 4: find the first index position where this is true */
: d = selectindex(c :!= 0)[1]
: d
4
: end
Run Code Online (Sandbox Code Playgroud)
您还可以2使用相同的逻辑在Step中找到感兴趣的字符串的位置.
这是以下之后的索引值.:
. mata:
: k = selectindex(a :== ".") + 1
: k
3
: end
Run Code Online (Sandbox Code Playgroud)
在这种情况下,Step 2变为:
. mata:
:
: b = tokens(a[k], "0")
: b
1 2 3 4
+-------------------------+
1 | 0 0 0 823 |
+-------------------------+
: end
Run Code Online (Sandbox Code Playgroud)
对于没有小数的意外情况:
foreach x in 124.000923 65.020923 1.000022030 12 0.0090843 .00000425 {
if strmatch("`x'", "*.*") mata: selectindex(tokens(tokens(st_local("x"), ".")[selectindex(tokens(st_local("x"), ".") :== ".") + 1], "0") :!= "0")[1]
else display " 0"
}
4
2
5
0
3
6
Run Code Online (Sandbox Code Playgroud)