Mata lacks a function that could transform (make uppercase, lowercase, etc.) a pattern inside a string. Imagine that you have 1600 string observations in a string variable and you must capitalize every letter after a comma.
Here's a way to do it, the ustrregextf and ustrregexta functions.
Now all one needs to type is
or, for strL,
NB The transformation function is passed as a string argument, not as a pointer. An improvised "eval()" is used (I added it to the topic title since people occasionally ask how to make an eval() in Mata).
Here's a way to do it, the ustrregextf and ustrregexta functions.
Code:
*! version 1.0.6 07oct2024
version 16.0
clear all
loc RS real scalar
loc SS string scalar
loc SM string matrix
mata:
mata set matastrict on
`SM' ustrregextf(`SM' s1, `SS' re, `SS' t,| `RS' noc)
{
`RS' i, j
`SS' g, s
noc = noc != . ? noc : 0
s = st_tempname()
for(i = 1; i <= rows(s1); i++) {
for(j = 1; j <= cols(s1); j++) {
(void) ustrregexm(s1[i,j], re, noc)
if ((g=ustrregexs(0)) != "") {
stata(`"mata: st_strscalar(""' + s + `"", "' +
t + `"(""' + g + `""))"')
s1[i,j] = usubinstr(s1[i,j], g, st_strscalar(s), 1)
}
}
}
return(s1)
}
`SM' ustrregexta(`SM' s1, `SS' re, `SS' t,| `RS' noc)
{
`RS' i, j
`SS' g, g_flag, s
noc = noc != . ? noc : 0
s = st_tempname()
for(i = 1; i <= rows(s1); i++) {
for(j = 1; j <= cols(s1); j++) {
while(1) {
(void) ustrregexm(s1[i,j], re, noc)
if ((g=ustrregexs(0)) != "" & g != g_flag) {
stata(`"mata: st_strscalar(""' + s + `"", "' +
t + `"(""' + g + `""))"')
s1[i,j] = usubinstr(s1[i,j], g, (g_flag=st_strscalar(s)), 1)
} else break
}
}
}
return(s1)
}
end
version 18.0: lmbuild llanguagetools.mlib, replace size(4)
Code:
mata: st_sview((X=""), ., "varname"); ustrregexta(X, ",\s*[a-z]", "ustrupper");
Code:
mata: st_sstore(., "varname", ustrregexta(st_sdata(., "varname"), ",\s*[a-z]", "ustrupper"))
