首页 > 解决方案 > 用于在数字列表成员周围环绕一些文本的单行

问题描述

假设我有一个看起来像这样的字符串序列:

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 中的 unicode 或 vanilla regex 函数是否有任何等价物?根据StataCorp 程序员的评论, Stata 的 ustrregex* 函数基于ICU 正则表达式引擎。

标签: regexunicodestata

解决方案


这里有两个问题:

  1. Stata 不支持您提到的那种正则表达式。
  2. 它的正则表达式函数不能处理诸如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"

推荐阅读