使用正则表达式或 subinstr() 清理局部宏

Using regular expressions or subinstr() to clean local macros

我的目标是从 _ 和单词末尾下划线后面的所有数字中清除给定的本地。假设我只有在单词末尾有下划​​线后跟数字。

通过使用 subinstr(),我可以指定我要消除 _1(并且可能循环不同的数字),但是双循环语法似乎过于复杂任务:

local list_x `" "rep78_3" "make_1" "price_1" "mpg_2" "'
local n_x : list sizeof list_x

forvalues j = 1/`n_x' {
    local varname: word `j' of `list_x'
    local clean_name: subinstr local varname "_1" "" 
    display "`clean_name'" 
}

我试图查看 regexm()regexs(),但我不太确定如何设置代码。

我知道可能有多种方法可以解决这个问题。

也许有更简单的方法可以解决我看不到的问题?

使用字符串函数:

local list_x rep78_3 make_1 price_1 mpg_2

// assumes only one _
foreach elem of local list_x {
    local pos = strpos("`elem'", "_")
    local clean = substr("`elem'", 1, `pos' - 1) 
    di "`clean'" 
}

// considers last _ (there can be multiple)
foreach elem of local list_x {
    local pos = strpos(reverse("`elem'"), "_")
    local clean = reverse(substr(reverse("`elem'"), `pos' + 1, .))
    di "`clean'" 
}

如果您愿意,可以嵌套函数调用。参见 help string functions

正则表达式也应该有效。

使用正则表达式,解决方案是:

local list_x `" "rep78_3" "make_1" "price_1" "mpg_2" "'
local n_x : list sizeof list_x

forval j = 1/`n_x' {
    local varname: word `j' of `list_x'
    local clean_name = regexr("`varname'" , "_[0-9]$" , "")
    di "`clean_name'" 
}

借助 Stata 14 中新版本的正则表达式函数,您可以一次替换所有匹配项。

. local list_x `" "rep78_3" "make_1" "price_1" "mpg_2" "'

. local fixed = ustrregexra(`"`list_x'"', "_[0-9]+","")

. dis `"`fixed'"'
 "rep78" "make" "price" "mpg" 

你可以通过组合 subinstr() 函数和 confirm 命令来做同样的事情:

local list_x rep78_3 make_1 price_1 mpg_2

local new_list_x = subinstr("`list_x'", "_", " ", .)

foreach x of local new_list_x {
    capture confirm number `x'
    if _rc != 0 {
        local final_list_x `final_list_x' `x'
    }
}

display "`final_list_x'"
rep78 make price mpg