2009-07-05 4 views
1

Bonjour,Extrait la sous-chaîne entre deux jetons. Deuxième jeton pourrait manquer

je besoin d'extraire la partie de chaîne qui peut ressemble à ceci:

"some_text MarkerA some_text_to_extract MarkerB some_text" 
"some_text MarkerA some_text_to_extract" 

Je dois extraire some_text_to_extract dans les deux cas. MarkerA, MarkerB - chaînes de texte prédéfinies.

J'ai essayé regexps, mais pas de chance:

".*\sMarkerA(.*)MarkerB.*" - does not work in case 2 
".*\sMarkerA(.*)(?=MarkerB)?.*" - wrong result "some_text_to_extract MarkerB some_text" 
".*\sMarkerA(.*)(?:MarkerB)?.*" - does not work at all 

Pourriez-vous s'il vous plaît aidez-moi cette question?

Répondre

0

Essayez:

".*\sMarkerA(.*?)(?=$|MarkerB)" 

Code d'essai:

#!/usr/bin/env python 

tests = [ 
     ("some_text MarkerA some_text_to_extract MarkerB some_text"," some_text_to_extract "), 
     ("some_text MarkerA some_text_to_extract"," some_text_to_extract") 
     ] 

import re 
reg = re.compile(r".*\sMarkerA(.*?)(?=$|MarkerB)") 

for (input,expected) in tests: 
    mo = reg.match(input) 
    assert mo is not None 
    print mo.group(1),expected 
    assert mo.group(1) == expected 
+0

Merci Douglas! C'était exactement ce dont j'avais besoin =) –

2

D'abord, se débarrasser de la .* au début et à la fin; vous n'avez pas besoin de faire correspondre toute la chaîne. Utilisez ensuite l'alternance pour faire correspondre le délimiteur de fin ou la fin de la chaîne.

"MarkerA(.*?)(?:MarkerB|$)" 
0

Le

".*\sMarkerA(.*)" 

Une partie de la regex correspondre à tout après Markera ne pas donner un changement pour MarkerB ou quoi que ce soit d'autre pour correspondre à égaler. Le. * Est gourmand, vous pouvez utiliser la forme non avide de *, *? pour donner:

".*\sMarkerA(.*)(?=MarkerB)?.*" 

Vous voulez probablement pas de capturer l'espace avant MarkerB donc dans ce cas, utilisez:

".*\sMarkerA(.*)(?=\sMarkerB)?.*" 
Questions connexes