Однострочник для переноса текста вокруг членов списка чисел
Предположим, у меня есть последовательность строк, которая выглядит примерно так:
1 10 46565 5968678 3 567 78
Я хотел бы превратить его в
F(1) F(10) F(46565) F(5968678) F(3) F(567) F(78)
Существует ли регулярное выражение с одной линией, которое выполнит это в Stata с произвольным числом элементов?
Я старался:
. display ustrregexra("1 10 46565 5968678 3 567 78","([:digit:]){1,}","XXX")
XXX XXX XXX XXX XXX XXX XXX
а также
. display ustrregexra("1 10 46565 5968678 3 567 78","([:digit:]){1,}","F(&)")
F(&) F(&) F(&) F(&) F(&) F(&) F(&)
а также
. display ustrregexra("1 10 46565 5968678 3 567 78","[0-9]{1,}","F(&)")
F(&) F(&) F(&) F(&) F(&) F(&) F(&)
В VI это, кажется, делает свое дело:
.s/[0-9]\{1,}/F(&)/g
Есть ли эквивалент в Stata для функций юникода или регулярного выражения? В соответствии с этим комментарием программиста StataCorp функции Stata ustrregex* основаны на механизме регулярных выражений ICU.
1 ответ
Здесь есть две проблемы:
- Stata не поддерживает регулярные выражения, о которых вы упоминаете.
- Его функции регулярного выражения не могут обрабатывать замены, такие как
F(\1)
,
Есть только один способ сделать это в одну (довольно длинную) строку:
clear
set obs 1
generate str = "1 10 46565 5968678 3 567 78"
local regex ([0-9]*)[ ]([0-9]*)[ ]([0-9]*)[ ]([0-9]*)[ ]([0-9]*)[ ]([0-9]*)[ ]([0-9]*)
generate new_str = "F(" + regexs(1) + ") " + ///
"F(" + regexs(2) + ") " + ///
"F(" + regexs(3) + ") " + ///
"F(" + regexs(4) + ") " + ///
"F(" + regexs(5) + ") " + ///
"F(" + regexs(6) + ") " + ///
"F(" + regexs(7) + ")" if regexm(str, "`regex'")
. list, abbreviate(10)
+--------------------------------------------------------------------------------+
| str new_str |
|--------------------------------------------------------------------------------|
1. | 1 10 46565 5968678 3 567 78 F(1) F(10) F(46565) F(5968678) F(3) F(567) F(78) |
+--------------------------------------------------------------------------------+
Очевидно, вы можете обобщить это и сделать его "истинным" одним вкладышем, написав небольшую программу.
РЕДАКТИРОВАТЬ:
Ниже приводится обобщение, которое также использует хитрость Роберта:
program define foo, rclass
local string `1'
local string = ustrregexra("`string'","\D"," ")
local string = ustrtrim(itrim("`string'"))
local string = ustrregexra("F("+"`string'"+")"," ", ") F(")
return local old_string `1'
return local new_string `string'
end
foo "1 10 46565 5968678 3 567 78"
return list
macros:
r(new_string) : "F(1) F(10) F(46565) F(5968678) F(3) F(567) F(78)"
r(old_string) : "1 10 46565 5968678 3 567 78"
foo "1xcvb10gh46565sdda5968678luiy3f567kl78"
return list
macros:
r(new_string) : "F(1) F(10) F(46565) F(5968678) F(3) F(567) F(78)"
r(old_string) : "1xcvb10gh46565sdda5968678luiy3f567kl78"