以下是数据样本:
part1
"Cambridge, Maryland TEST MODEL SEADROME"
"L.B. MAYER HONORED"
"A TOWN MOVES"
"U.S. SAVINGS BONDS RALLY"
"N.D. NOSES OUT S.M.U. BY 27 TO 20"
"Philadelphia, Pa. BURN 2,300 SQUEALERS"
"Odd Bits In To-day's News"
"Saratoga Springs, N.Y. DIAVOLO IS STAR AT BRILLIANT SPA OPENING"
"Risk Death in Daring Race"
"Philadelphia, PA. IT'S HIGHER EDUCATION"
"806 DECORATIONS"
"Snow Hauled 20 Miles For Skiers"
"F.D.R. ASKS VICTORY EFFORT"
每个字符串都有大写和小写部分,或全部为大写。我一直在尝试使用正则表达式来仅提取字符串的大写部分,但没有任何运气。我能做的最好的事情是识别字符串何时开始或以特定数量的大写字符结尾:
generate title = regexs(0) if regexm(part1, "^[A-Z][A-Z][A-Z].*[A-Z][A-Z][A-Z]$")
我也尝试过以下内容,我在论坛中提出了另一个问题:
generate title = regexs(0) if(regexm(part1, "\b[A-Z]{2,}\b"))
应该在一行中查找至少包含两个大写字母的单词,但它只会为我返回缺少的值。我正在使用Stata版本13.1 for Mac。
答案 0 :(得分:0)
正如@stribizhev指出的那样,否定可能是一种方式:
clear
set more off
input ///
str70 myvar
"Cambridge, Maryland TEST MODEL SEADROME"
"L.B. MAYER HONORED"
"A TOWN MOVES"
"U.S. SAVINGS BONDS RALLY"
"N.D. NOSES OUT S.M.U. BY 27 TO 20"
"Philadelphia, Pa. BURN 2,300 SQUEALERS"
"Odd Bits In To-day's News"
"Saratoga Springs, N.Y. DIAVOLO IS STAR AT BRILLIANT SPA OPENING"
"Risk Death in Daring Race"
"Philadelphia, PA. IT'S HIGHER EDUCATION"
"806 DECORATIONS"
"Snow Hauled 20 Miles For Skiers"
"F.D.R. ASKS VICTORY EFFORT"
end
gen title = trim(regexs(2)) if regexm(myvar, "([,.]*)([^a-z]*$)")
list title
结果是
. list title
+-----------------------------------------------+
| title |
|-----------------------------------------------|
1. | TEST MODEL SEADROME |
2. | L.B. MAYER HONORED |
3. | A TOWN MOVES |
4. | U.S. SAVINGS BONDS RALLY |
5. | N.D. NOSES OUT S.M.U. BY 27 TO 20 |
|-----------------------------------------------|
6. | BURN 2,300 SQUEALERS |
7. | |
8. | N.Y. DIAVOLO IS STAR AT BRILLIANT SPA OPENING |
9. | |
10. | PA. IT'S HIGHER EDUCATION |
|-----------------------------------------------|
11. | 806 DECORATIONS |
12. | |
13. | F.D.R. ASKS VICTORY EFFORT |
+-----------------------------------------------+
我认为这与你想要的很接近,但并不完美。如果他们没有一些规则的结构,那么很难想象一种简单的清理字符串的方法。例如,比较观测值6和10的输入/输出。
如果你有一个titles数据库,在初步清理之后,你可以比较和匹配。例如,请参阅ssc describe strgroup
。
答案 1 :(得分:0)
问题的含义似乎是您希望正则表达式规范能够提取所有实例。无论多么合理,正如Stata中的正则表达式一样。你需要一个循环实例。这使用moss
(ssc install moss
),这是其主要目的。 (如果他正在阅读这篇文章,那么收集苔藓的暗示是第二个有关作者的典型虚弱文字游戏。)
clear
input str100 part1
"Cambridge, Maryland TEST MODEL SEADROME"
"L.B. MAYER HONORED"
"A TOWN MOVES"
"U.S. SAVINGS BONDS RALLY"
"N.D. NOSES OUT S.M.U. BY 27 TO 20"
"Philadelphia, Pa. BURN 2,300 SQUEALERS"
"Odd Bits In To-day's News"
"Saratoga Springs, N.Y. DIAVOLO IS STAR AT BRILLIANT SPA OPENING"
"Risk Death in Daring Race"
"Philadelphia, PA. IT'S HIGHER EDUCATION"
"806 DECORATIONS"
"Snow Hauled 20 Miles For Skiers"
"F.D.R. ASKS VICTORY EFFORT"
end
compress
moss part1, match("([A-Z]+)") regex
egen wanted = concat(_match*), p(" ")
l wanted
+--------------------------------------------------+
| wanted |
|--------------------------------------------------|
1. | C M TEST MODEL SEADROME |
2. | L B MAYER HONORED |
3. | A TOWN MOVES |
4. | U S SAVINGS BONDS RALLY |
5. | N D NOSES OUT S M U BY TO |
|--------------------------------------------------|
6. | P P BURN SQUEALERS |
7. | O B I T N |
8. | S S N Y DIAVOLO IS STAR AT BRILLIANT SPA OPENING |
9. | R D D R |
10. | P PA IT S HIGHER EDUCATION |
|--------------------------------------------------|
11. | DECORATIONS |
12. | S H M F S |
13. | F D R ASKS VICTORY EFFORT |
+--------------------------------------------------+
我假设你想要结果之间的空格;否则很难理解。你没有在大写之间指定标点符号;如果你想要,你需要相应地修改正则表达式。
答案 2 :(得分:0)
我想不出一个单一的规则会用一个命令干净地解析这种类型的数据。通常,最好的策略是针对简单案例然后转向更加困难的案例,直到收益递减使得额外的尝试没有吸引力。
在使用正则表达式时注意意外匹配很重要,特别是在观察次数很多的情况下。我使用listsome
(来自SSC)进行此类工作。
看起来part1
通常以城市名称开头,后跟州名/缩写。这是处理简单案例和城市/州案例的代码:
clear
input str60 part1
"Cambridge, Maryland TEST MODEL SEADROME"
"L.B. MAYER HONORED"
"A TOWN MOVES"
"U.S. SAVINGS BONDS RALLY"
"N.D. NOSES OUT S.M.U. BY 27 TO 20"
"Philadelphia, Pa. BURN 2,300 SQUEALERS"
"Odd Bits In To-day's News"
"Saratoga Springs, N.Y. DIAVOLO IS STAR AT BRILLIANT SPA OPEN"
"Risk Death in Daring Race"
"Philadelphia, PA. IT'S HIGHER EDUCATION"
"806 DECORATIONS"
"Snow Hauled 20 Miles For Skiers"
"F.D.R. ASKS VICTORY EFFORT"
end
* take care of the easy cases where there are no lowercase letters
gen title = part1 if !regexm(part1,"[a-z]")
* this type of string work is easier if text is aligned to the left
leftalign // (from SSC)
* target cases of City, State at the start of part1.
* with complex patterns, it's easy to miss unintended matches when
* lots of obs are involved so use -listsome- (from SSC to track changes)
gen title0 = title
replace title = trim(regexs(3)) if regexm(part1,"^([A-Z][a-z ]*)+, ([A-Z][a-z]*\.?)+([^a-z]+$)")
listsome if title != title0
list part1 title