Stata、正则表达式与文本处理

Stata、正则表达式与文本处理

在使用Stata进行数据处理的时候,很多时候使用正则表达式能够极大地简化工作,这篇文章汇总了我之前收集的一些使用Stata进行文本处理的技巧。

一些字符串函数

假如有这么一道题目,要求匹配出字符串”1 11 51 71 91”中的数。下面给出了几种方法:

strpos(s1,s2)

字符串s2在s1中首先被发现的位置,如果没有者返回0。

Stata
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
clear
set obs 100
gen id = _n
gen num = "1 11 51 71 91"
gen match = 1 if strpos(num, string(id))
list if match==1

* 结果
. list if match==1
+----------------------------+
| id num match |
|----------------------------|
1. | 1 1 11 51 71 91 1 |
5. | 5 1 11 51 71 91 1 |
7. | 7 1 11 51 71 91 1 |
9. | 9 1 11 51 71 91 1 |
11. | 11 1 11 51 71 91 1 |
|----------------------------|
51. | 51 1 11 51 71 91 1 |
71. | 71 1 11 51 71 91 1 |
91. | 91 1 11 51 71 91 1 |
+----------------------------+

显然这种方法的问题在于把数字割裂开来了。

word()

word()函数对num中的数字进行提取,然后使用real()函数从字符型转换成数值型,并与id进行匹配:

Stata
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
clear
set more off
set obs 100
gen num = "1 11 51 71 91"
gen match = 0
gen id = _n
local n = wordcount(num)
qui forval i = 1(1)`n'{
replace match = 1 if real(word(num,`i')) == id
}
list if match == 1

* 结果

. list if match == 1
+----------------------------+
| num match id |
|----------------------------|
1. | 1 11 51 71 91 1 1 |
11. | 1 11 51 71 91 1 11 |
51. | 1 11 51 71 91 1 51 |
71. | 1 11 51 71 91 1 71 |
91. | 1 11 51 71 91 1 91 |
+----------------------------+

这个提取结果就是正确的了。

split命令

该方法是使用split命令进行分割然后判断:

Stata
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
clear
set more off
set obs 100
gen num = "1 11 51 71 91"
gen match = 0
gen id = _n
split num, p(" ")
replace match = (string(id) == num1) + (string(id) == num2) + (string(id) == num3) + (string(id) == num4) + (string(id) == num5)
list id num match if match == 1

* 结果
. list id num match if match == 1
+----------------------------+
| id num match |
|----------------------------|
1. | 1 1 11 51 71 91 1 |
11. | 11 1 11 51 71 91 1 |
51. | 51 1 11 51 71 91 1 |
71. | 71 1 11 51 71 91 1 |
91. | 91 1 11 51 71 91 1 |
+----------------------------+

Stata
1
2
3
4
5
6
7
8
9
10
11
12
13
/* 还可以把上面的换成循环语句 */
clear
set more off
set obs 100
gen num = "1 11 51 71 91"
gen match = 0
gen id = _n
split num, p(" ")
local n = r(nvars)
forval i = 1(1)`n'{
replace match = match + (string(id) == num`i')
}
list id num match if match == 1
Stata
1
2
3
4
5
6
7
8
9
/* 还可以继续优化 */
clear
set more off
set obs 100
gen num = "1 11 51 71 91"
gen match = 0
gen id = _n
replace match = 1 if strpos(" "+ num + " ", " " + string(id) + " ")
list if match == 1 /* 注意上面一行命令中内外双引号之间有空格的 */

一个正则表达式的例子

Stata
1
2
3
4
5
clear all
set obs 1
gen v = "中国人寿保险(集团)公司(China Life Insurance)"
gen a = regexs(1) if regexm(v, "^(.*)\((.*)\)")
gen b = regexs(2) if regexm(v, "^(.*)\((.*)\)")

结果:
变量 | 变量值
:-: | :-:
v | 中国人寿保险(集团)公司(China Life Insurance)
a | 中国人寿保险(集团)公司
b | China Life Insurance

与正则表达式有关的字符串函数

ustrregexm(s,re[, noc])

如果字符串s中匹配到re(正则表达式),则返回1,否则返回0;

Stata
1
2
3
4
ustrregexm("12345", "([0-9]){5}") = 1
ustrregexm("de TRÈS près", "rès") = 1
ustrregexm("de TRÈS près", "Rès") = 0
ustrregexm("de TRÈS près", "Rès", 1) = 1

当指定noc且noc不为0时,表示忽略大小写的差异。

ustrregexrf(s1,re,s2[,noc])

把字符串s1中匹配re的第一个子字符串替换成s2。

Stata
1
2
3
ustrregexrf("très près", "rès", "X") = "tX près"
ustrregexrf("TRÈS près", "Rès", "X") = "TRÈS près"
ustrregexrf("TRÈS près", "Rès", "X", 1) = "TX près"

当指定noc且noc不为0时,表示忽略大小写的差异。

ustrregexra(s1,re,s2[,noc])

把字符串s1中匹配re的所有子字符串替换成s2。

Stata
1
2
3
ustrregexra("très près", "rès", "X") = "tX pX"
ustrregexra("TRÈS près", "Rès", "X") = "TRÈS près"
ustrregexra("TRÈS près", "Rès", "X", 1) = "TX pX"

当指定noc且noc不为0时,表示忽略大小写的差异。

ustrregexs(n)

表示ustrregexm()匹配到的第n个字符串。当n为0时表示整个正则表达式匹配项。

正则表达式的使用

贪婪模式

贪婪模式:首先看整个字符串是否能与正则表达式匹配,如果匹配不成功,会去掉该字符串的最后一个字符,并尝试再次匹配,如果匹配还是不成功,那么再去掉此时的最后一个字符直到发现匹配或者全部尝试过后仍然无法匹配。

Stata
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
set obs 10
gen v = "A"+"B"*(_n-1)
gen v1 = ustrregexs(0) if ustrregexm(v,"AB*")
//元字符*表示匹配前一个字符或子表达式任意次,即零次或多次
gen v2 = ustrregexs(0) if ustrregexm(v,"AB+")
//元字符+表示匹配前一个字符或子表达式至少一次,即一次或多次
gen v3 = ustrregexs(0) if ustrregexm(v,"AB?")
//元字符?表示匹配前一个字符或子表达式零次或一次
gen v4 = ustrregexs(0) if ustrregexm(v,"AB{1,3}")
//元字符{n1,n2}表示匹配前一个字符或子表达式至少n1次,至多n2次
gen v5 = ustrregexs(0) if ustrregexm(v,"AB{3,}")
. list, sep(0)

+---------------------------------------------------------------+
| v v1 v2 v3 v4 v5 |
|---------------------------------------------------------------|
1. | A A A |
2. | AB AB AB AB AB |
3. | ABB ABB ABB AB ABB |
4. | ABBB ABBB ABBB AB ABBB ABBB |
5. | ABBBB ABBBB ABBBB AB ABBB ABBBB |
6. | ABBBBB ABBBBB ABBBBB AB ABBB ABBBBB |
7. | ABBBBBB ABBBBBB ABBBBBB AB ABBB ABBBBBB |
8. | ABBBBBBB ABBBBBBB ABBBBBBB AB ABBB ABBBBBBB |
9. | ABBBBBBBB ABBBBBBBB ABBBBBBBB AB ABBB ABBBBBBBB |
10. | ABBBBBBBBB ABBBBBBBBB ABBBBBBBBB AB ABBB ABBBBBBBBB |
+---------------------------------------------------------------+

值得注意的一点是,贪婪模式并不意味着我们匹配出的是整个字符串中所能匹配到的最长的子字符串,而是尽可能靠近字符串开头位置的匹配的最长字符串。

Stata
1
2
3
4
5
6
7
8
9
10
clear all
set obs 1
gen str v = "123a4567"
gen v1 = ustrregexs(0) if ustrregexm(v,"\d+")
list
+----------------+
| v v1 |
|----------------|
1. | 123a4567 123 |
+----------------+

元字符\d表示1-9任意一个数字,等价于[0-9],正则表达式”\d+”则表示至少一个的连续数字,根据贪婪法很容易理解,最后匹配的结果是123。

懒惰模式

懒惰模式:首先看第一个字符是否匹配,如果不匹配,就读入下一个字符组成两个字符的字符串进行匹配检查,如此继续直到读入整个字符串,然后再从开头一个个地删除字符,直到成功匹配。在正则表达式的最后加上一个问号就会进入懒惰模式。

Stata
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
clear all
set obs 10
gen v = "A" + "B"*(_n-1)
gen v1 = ustrregexs(0) if ustrregexm(v,"AB*?")
gen v2 = ustrregexs(0) if ustrregexm(v,"AB+?")
gen v3 = ustrregexs(0) if ustrregexm(v,"AB??")
gen v4 = ustrregexs(0) if ustrregexm(v,"AB{1,3}?")
gen v5 = ustrregexs(0) if ustrregexm(v,"AB{3,}?")
list, sep(0)
+---------------------------------------+
| v v1 v2 v3 v4 v5 |
|---------------------------------------|
1. | A A A |
2. | AB A AB A AB |
3. | ABB A AB A AB |
4. | ABBB A AB A AB ABBB |
5. | ABBBB A AB A AB ABBB |
6. | ABBBBB A AB A AB ABBB |
7. | ABBBBBB A AB A AB ABBB |
8. | ABBBBBBB A AB A AB ABBB |
9. | ABBBBBBBB A AB A AB ABBB |
10.| ABBBBBBBBB A AB A AB ABBB |
+---------------------------------------+

懒惰模式并不是意味着我们匹配出了整个字符串中所能匹配到的最
短字符串,而是尽可能靠近开头位置的最短字符串。

Stata
1
2
3
4
5
6
7
8
9
10
11
clear all
set obs 1
gen str v = "aaaaab"
gen v1 = ustrregexs(0) if ustrregexm(v,"a+?b")
//"a+?b",表示至少一个a并且最后紧跟着b
list
+-----------------+
| v v1 |
|-----------------|
1. | aaaaab aaaaab |
+-----------------+

正则表达式之汉字匹配

gen u2 = ustrregexs(0) if ustrregexm(v,”[\u4e00-\u9fa5]+”)
gen u1 = ustrregexs(1) if ustrregexm(v,”[a-zA-z]+(.+?)\d”)

思路

  • 如果我们知道每一个汉字的编码,就可以实现使用字符串函数匹配到汉字。
  • 在Stata函数中有ustrunescape(s)和ustrtohex(s[,n])两个函数可以实现Unicode转义字符的解码与编码。
  1. ustrunescape(s):将unicode转义字符s进行解码。
  2. ustrtohex(s[,n]):将字符s从第n个Unicode字符开始进行编码,转换成unicode转义字符。
Stata
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
. dis ustrtohex("暨南大学")
\u66a8\u5357\u5927\u5b66

. dis ustrunescape("\u66a8\u5357\u5927\u5b66")
暨南大学

. dis ustrtohex("暨南大学",2)
\u5357\u5927\u5b66

. dis ustrtohex("暨南大学")
\u66a8\u5357\u5927\u5b66

. dis ustrunescape("\u66a8\u5357\u5927\u5b66")
暨南大学

. dis ustrtohex("暨南大学",2)
\u5357\u5927\u5b66
  • Unicode编码可以直接应用于正则表达式中,例如:
  1. 0-9的Unicode转义字符为\u0030-\u0039
  2. \d即[0-9]可以表示为[\u0030-\u0039]
  3. 基本汉字的Unicode编码范围为\u4e00-\u9fa5
Stata
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
. clear all
. input str40 v

v
1. Xiaomao小猫1
2. xiaogou小狗2
3. xiaoji小鸡3
4. xiaoyu小鱼4
5. xiaozhu小猪5
6. xiaoniu小牛6
7. xiaoniao小鸟7
8. end

. gen u1 = ustrregexs(1) if ustrregexm(v,"[a-zA-z]+(.+?)\d")

. list, sep(0)

+----------------------+
| v u1 |
|----------------------|
1. | Xiaomao小猫1 小猫 |
2. | xiaogou小狗2 小狗 |
3. | xiaoji小鸡3 小鸡 |
4. | xiaoyu小鱼4 小鱼 |
5. | xiaozhu小猪5 小猪 |
6. | xiaoniu小牛6 小牛 |
7. | xiaoniao小鸟7 小鸟 |
+----------------------+
.
. gen u2 = ustrregexs(0) if ustrregexm(v,"[\u4e00-\u9fa5]+")

. list, sep(0)

+-----------------------------+
| v u1 u2 |
|-----------------------------|
1. | Xiaomao小猫1 小猫 小猫 |
2. | xiaogou小狗2 小狗 小狗 |
3. | xiaoji小鸡3 小鸡 小鸡 |
4. | xiaoyu小鱼4 小鱼 小鱼 |
5. | xiaozhu小猪5 小猪 小猪 |
6. | xiaoniu小牛6 小牛 小牛 |
7. | xiaoniao小鸟7 小鸟 小鸟 |
+-----------------------------+

. dis ustrunescape("\u9fa5")


. gen u3 = ustrregexs(0) if ustrregexm(v,"[一-龥]+")

. list, sep(0)

+------------------------------------+
| v u1 u2 u3 |
|------------------------------------|
1. | Xiaomao小猫1 小猫 小猫 小猫 |
2. | xiaogou小狗2 小狗 小狗 小狗 |
3. | xiaoji小鸡3 小鸡 小鸡 小鸡 |
4. | xiaoyu小鱼4 小鱼 小鱼 小鱼 |
5. | xiaozhu小猪5 小猪 小猪 小猪 |
6. | xiaoniu小牛6 小牛 小牛 小牛 |
7. | xiaoniao小鸟7 小鸟 小鸟 小鸟 |
+------------------------------------+

正则表达式中的转义字符

Stata
1
2
3
4
5
6
7
8
9
10
11
12
clear
set obs 1
gen result1 = "blue|glue"
gen result2 = ustrregexs(1) if ustrregexm(result1,"|(.*)")
gen result3 = ustrregexs(1) if ustrregexm(result1,"\|(.*)")
list

+-------------------------------+
| result1 result2 result3 |
|-------------------------------|
1. | blue|glue glue |
+-------------------------------+
Stata
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
clear
set obs 5
input strL prov

prov
1. "黑|黑龙江"
2. "吉|吉林"
3. "辽|辽宁"
4. "安徽"
5. "鲁"
save prov, replace

use prov, clear
gen prov1 = ustrregexs(1) if ustrregexm(prov, "\|(.*)")
list

+--------------------+
| prov prov1 |
|--------------------|
1. | 黑|黑龙江 黑龙江 |
2. | 吉|吉林 吉林 |
3. | 辽|辽宁 辽宁 |
4. | 安徽 |
5. | 鲁 |
+--------------------+

gen prov2 = ustrregexra(prov, ".+\|","")
gen prov3 = ustrregexra(prov, ".+\|(.*)","$1")
list

+--------------------------------------+
| prov prov1 prov2 prov3 |
|--------------------------------------|
1. | 黑|黑龙江 黑龙江 黑龙江 黑龙江 |
2. | 吉|吉林 吉林 吉林 吉林 |
3. | 辽|辽宁 辽宁 辽宁 辽宁 |
4. | 安徽 安徽 安徽 |
5. | 鲁 鲁 鲁 |
+--------------------------------------+

split prov, parse(|) gen(prov4)
gen prov5 = prov if index(prov, "|") == 0
replace prov5 = prov42 if prov5 == ""
drop prov41 prov42
rename prov5 prov4
list

+-----------------------------------------------+
| prov prov1 prov2 prov3 prov4 |
|-----------------------------------------------|
1. | 黑|黑龙江 黑龙江 黑龙江 黑龙江 黑龙江 |
2. | 吉|吉林 吉林 吉林 吉林 吉林 |
3. | 辽|辽宁 辽宁 辽宁 辽宁 辽宁 |
4. | 安徽 安徽 安徽 安徽 |
5. | 鲁 鲁 鲁 鲁 |
+-----------------------------------------------+

字符串函数、正则表达式与变量拆分

Stata
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
//split命令的格式:split strvar [if] [in] [, options]
//最常用的options是parse()
clear all
global PATH "D:\Desktop\Stata笔记"
cd $PATH
set obs 4
input str20 name
"John Smith"
"Mike Hunter"
"Mary Miller"
"Bill Cliton"

split name, parse(" ")
rename (name1 name2) (firstname lastname)

//如果没有统一的分隔符号该如何拆分呢?
clear all
global PATH "D:\Desktop\Stata笔记"
cd $PATH

set obs 5
input byte subject_ID str20 SexAge_Race
1 "MALE41.2_White"
2 "FEMALE42.9_White"
3 "FEMALE38.5_White"
4 "FEMALE35.6_Hispanic"
5 "FEMALE48.5_White"
list

//方法一
preserve
gen Sex = "FEMALE" if substr(SexAge_Race, 1, 6) == "FEMALE"
replace Sex = "MALE" if substr(SexAge_Race, 1, 4) == "MALE"
gen work = subinstr(SexAge_Race, Sex, "", .)
//subinstr(s1,s2,s3,n): 把字符串s1中的第n个子字符串s2用s3代替
split work, parse(_) destring
rename (work1 work2) (Age Race)
drop SexAge_Race work
list

//方法二: 使用正则表达式
/*
1: ustrregexm(s,re[, noc]): u代表unicode,reg代表regular,ex代表expression,m代表match
s代表字符串,"re"代表正则表达式,如果字符串中有正则表达式匹配的内容就赋值为1,否则
赋值为0。noc这个部分可以填上一个数字,如果你定义了noc并且是一个不为0的数字,那么正
则表达式和字符串匹配时将不区分大小写。
2:ustrregexs(n):s代表substring
n为非负整数,代表ustrregexm(s,re)函数中的第n个子表达式对应的字符串。若n为0,则代表
引号中所有表达式对应的子字符串。usterexs函数必须在ustrregexm函数运行完之后才能运行,
可用于提取子字符串。
正则表达式中常用的元字符:
1: \ 后向引用,后面跟正则表达式中的某个字符,表示匹配该符号。例如,"\\"表示匹配"\";
"\_"表示匹配 "_"
2: ^ 在表达式的开头位置,表示接下来的表达式所匹配的内容位于字符串开始的位置。
3: $ 在表达式结尾的位置,表示接下来的表达式所匹配的内容位于字符串结尾的位置。
4: * 表示将前一个字符或子表达式匹配任意次。
5: + 表示将前一个字符或子表达式至少匹配一次。
5: ? 表示将前一个字符或子表达式匹配一次或0次
6: {n} 表示将前一个字符或子表达式匹配n次
7: 0 创建一个子表达式,可以提取或者替换括号内的子表达式对应的字符串。
8: | 逻辑运算符,表示对该符号之前或之后的字符或子表达式进行匹配。
9: - 指定一个范围。
10: [] 方括号内的字符之一将用来进行匹配。
*/
restore
list
preserve
gen Sex = ustrregexs(1) if ustrregexm(SexAge_Race, "(.*?)\d")
gen Age = real(ustrregexs(1)) if ustrregexm(SexAge_Race, "[A-Z]*(.*)_")
gen Race = ustrregexs(1) if ustrregexm(SexAge_Race, "_(.*)")
list

//除此之外还可以使用正则表达式进行提取

restore
list
gen Sex = ustrregexs(1) if ustrregexm(SexAge_Race, "(.+?)(\d.+?)_(.+)")
gen Age = real(ustrregexs(2)) if ustrregexm(SexAge_Race, "(.+?)(\d.+?)_(.+)")
gen Race = ustrregexs(3) if ustrregexm(SexAge_Race, "(.+?)(\d.+?)_(.+)")
list

moss命令、正则表达式与简单的文本分析

Stata
1
2
3
4
5
6
7
8
9
10
11
12
13
14
clear
set more off
input str50 author
"O. B. Tofler and T. L. Woodings"
"G. E. Vaillant"
"U. Bauer and A. Hasenohrl"
"D. J. Pittman and R. L. Tate"
"S. Pell and C. A. D'Alonzo"
end
* 然后使用moss命令和正则表达式来提取
moss author, match("([A-Z][a-z]+)") regex
* 我们可以通过prefix和suffix两个选项来修改生成的变量名的前缀和后缀
moss author, match("([A-Z][a-z]+)") regex prefix(s)
moss author, match("([A-Z][a-z]+)") regex suffix(p)

下面我们来查找This is a cat.中的is的数量,为了避免This中的is被提取,我们在is前后都加上空格:

Stata
1
2
3
4
clear
set obs 1
gen a = "This is a cat."
moss a, match(" is ")

使用正则表达式匹配需要用到元字符\b,它所匹配的就是单词边界, unicode选项在这里表示我们用Stata14中的字符串函数:

Stata
1
2
3
4
5
6
7
8
9
clear
set obs 1
gen a = "This is a cat."
moss a, match("(\bis\b)") regex unicode

clear
set obs 1
gen a = "This is a cat."
moss a, match("(\bcat)") regex unicode

regexr——正则表达式的替换函数

Stata
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
* 正则表达式的替换函数
clear all
input strL city
"1.北京"
"上海"
"3.广州"
"深圳"
end

* 现在想要去掉数字序号
replace city = regexr(city, "[0-9]+\.", "")
list city

+------+
| city |
|------|
1. | 北京 |
2. | 上海 |
3. | 广州 |
4. | 深圳 |
+------+

大小写转换

Stata
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
clear all
set obs 3
input str20 var1 str20 name
"WEIBO" "hua zeng"
"QQ" "zijian xu"
"wechat" "jie su"

gen name_proper = proper(name)
list

+--------------------------------+
| var1 name name_pr~r |
|--------------------------------|
1. | WEIBO hua zeng Hua Zeng |
2. | QQ zijian xu Zijian Xu |
3. | wechat jie su Jie Su |
+--------------------------------+

gen var1_lower = lower(var1)
gen var2_upper = upper(var1_lower)
list

+------------------------------------------------------+
| var1 name name_pr~r var1_l~r var2_u~r |
|------------------------------------------------------|
1. | WEIBO hua zeng Hua Zeng weibo WEIBO |
2. | QQ zijian xu Zijian Xu qq QQ |
3. | wechat jie su Jie Su wechat WECHAT |
+------------------------------------------------------+

Stata分词

  • ustrwordcount(): ustrwordcount(s[,local])
  1. s: string
  2. loc: indicate language environment, for example: “en” “cn”. default is “cn”
  • 该函数返回的是字符串s中的非空的unicode单词的个数,需要指明的是unicode单词与由word()函数返回的单词不同,word(s,n)函数返回的是字符串s中的第n个以空白字符分隔的字符串,而ustrwordcount()是以unicode单词为基础,返回unicode中非空的unicode单词的数量,unicode单词是遵循一些语言的单词边界规则或字典的语言单位。
Stata
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
. di word("你好 世界", 2)
世界

. di ustrwordcount("你好 世界是美好的", "cn")
5

. di ustrword("世界是美好的", 4, "cn")


. clear all

. set obs 1

. gen v = `"小明说:“我先吃水果然后喝汽水,果然拉肚子了。”这里有两个果然,但只有第二个果然是一个词。"'

. di "`=v[1]'"
小明说:“我先吃水果然后喝汽水,果然拉肚子了。”这里有两个果然,但只有第二个果然是一个词。

. gen v1 = ""

forvalues i = 1/`=ustrwordcount("`=v[1]'", "cn")' {
qui replace v1 = v1 + ustrword("`=v[1]'", `i', "cn") + " "
}

. di "`=v1[1]'"
小明 说 : “ 我 先吃 水果 然后 喝 汽水 , 果然 拉肚子 了 。 ” 这里 有 两 个 果然 , 但 只有 第二个 果然是 一个 词 。
# Stata

评论

程振兴

程振兴 @czxa.top
截止今天,我已经在本博客上写了659.4k个字了!

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×