2017-03-23 3 views
2

Comment implémenter une correspondance non gourmande dans Stata en utilisant regex? Ou est-ce que Stata a même cette capacité?Correspondance non gourmande (paresseuse) avec regex?

Je veux extraire tout le texte qui se produit entre un hashtag "#" et un point ".".

code Exemple:

clear 
set obs 3 
generate var1="anything#aaabbbccc.dddeee.fff" in 1 
replace var1="anything#aaabbbccc.dddeee" in 2 
replace var1="anything#aaabbbccc." in 3 
generate var2=regexs(1) if regexm(var1,"#(.*)\.") 
list 

Mais dans Stata (v.13.1), je ne peux pas sembler être en mesure d'utiliser le caractère non gourmand #(.*?)\.. Ainsi, le code ci-dessus donne ceci:

+--------------------------------------------------+ 
|       var1    var2 | 
|--------------------------------------------------| 
| anything#aaabbbccc.dddeee.fff aaabbbccc.dddeee | 
|  anything#aaabbbccc.dddeee   aaabbbccc | 
|   anything#aaabbbccc.   aaabbbccc | 
+--------------------------------------------------+ 

Mais ce que je veux est ceci:

+--------------------------------------------------+ 
|       var1    var2 | 
|--------------------------------------------------| 
| anything#aaabbbccc.dddeee.fff   aaabbbccc | 
|  anything#aaabbbccc.dddeee   aaabbbccc | 
|   anything#aaabbbccc.   aaabbbccc | 
+--------------------------------------------------+ 

Répondre

4

Un jeu sur l'utilisation #(.*?)\. serait de correspondre à peu importe quel caractère non point se produisant après le signe dièse, à savoir ce motif:

#([^.]*) 

Essayez ce code:

clear 
set obs 3 
generate var1="anything#aaabbbccc.dddeee.fff" in 1 
replace var1="anything#aaabbbccc.dddeee" in 2 
replace var1="anything#aaabbbccc." in 3 
generate var2=regexs(1) if regexm(var1,"#([^.]*)") 
list 

Demo

+0

Simple, efficace. Je vous remercie! – user812783765

0

Une fois que beaucoup de programmeurs ont appris sur les expressions régulières, ils sont réticents à chercher ailleurs dans la gestion de la chaîne, et avec raison.

Ceci est juste pour signaler que le problème donné, et bien d'autres encore, il existe une alternative piétonne:

clear 
set obs 3 
generate var1="anything#aaabbbccc.dddeee.fff" in 1 
replace var1="anything#aaabbbccc.dddeee" in 2 
replace var1="anything#aaabbbccc." in 3 
generate var2=regexs(1) if regexm(var1,"#([^.]*)") 

gen where1 = strpos(var1, "#") + 1 
gen where2 = strpos(var1, ".") 
gen var3 = substr(var1, where1, where2 - where1) 

list 


    +-------------------------------------------------------------------------+ 
    |       var1  var2 where1 where2  var3 | 
    |-------------------------------------------------------------------------| 
    1. | anything#aaabbbccc.dddeee.fff aaabbbccc  10  19 aaabbbccc | 
    2. |  anything#aaabbbccc.dddeee aaabbbccc  10  19 aaabbbccc | 
    3. |   anything#aaabbbccc. aaabbbccc  10  19 aaabbbccc | 
    +----------------------------------------------------------------------- 

Trouver les positions de début et de fin de la sous-chaîne que vous voulez, et extrait ce qui se trouve entre. Cela manque résolument de style, mais parfois vous y arrivez plus vite. Rappelez-vous toujours de tenir compte du temps du programmeur dans l'élaboration de l'expression régulière dont vous avez besoin.