2016-05-09 7 views
4

ich eine Liste von Strings haberegex Extrakt verschiedene Teile einer Zeichenfolge in konsistenter Reihenfolge

my_strings = [ 
    "2002-03-04 with Matt", 
    "Important: 2016-01-23 with Mary", 
    "with Tom on 2015-06-30", 
] 

Ich mag extrahieren:

  • Datum (immer in yyyy-mm-dd-Format)
  • Person (immer mit Person), aber ich will nicht halten „mit“

ich tun konnte:

import re 
pattern = r'.*(\d{4}-\d{2}-\d{2}).*with \b([^\b]+)\b.*' 
matched = [re.match(pattern, x).groups() for x in my_strings] 

aber es schlägt fehl, weil das Muster nicht "with Tom on 2015-06-30" entspricht.

Frage s

Wie gebe ich die RegexMuster die Reihenfolge gleichgültig zu sein, in dem Datum oder der Person in der Zeichenfolge erscheinen?

und

Wie stelle ich sicher, dass die groups() Methode, um sie in der gleichen Reihenfolge kehrt jedes Mal?

Ich erwarte, dass die Ausgabe so aussieht?

[('2002-03-04', 'Matt'), ('2016-01-23', 'Mary'), ('2015-06-30', 'Tom')] 

Antwort

2

Wenn Sie Python neue regex verwenden Modul können Sie conditionals verwenden
ein garantiertes Spiel auf 2 Artikel zu erhalten.

Ich würde denken, das ist eher wie ein Standard zu tun out-of-order passend.

(?:.*?(?:(?(1)(?!))\b(\d{4}-\d\d-\d\d)\b|(?(2)(?!))with[ ](\w+))){2}

Expanded

(?: 
     .*? 
     (?: 
      (?(1)(?!)) 
      \b 
      (\d{4} - \d\d - \d\d)  # (1) 
      \b 
     | (?(2)(?!)) 
      with [ ] 
      (\w+)      # (2) 
    ) 
){2} 
2

sollte diese Arbeit:

my_strings = [ 
    "2002-03-04 with Matt", 
    "Important: 2016-01-23 with Mary", 
    "with Tom on 2015-06-30", 
] 

import re 

alternates = r"(?:\b(\d{4}-\d\d-\d\d)\b|with (\w+)|.)*" 

for tc in my_strings: 
    print(tc) 
    m = re.match(alternates, tc) 
    if m: 
     print("\t", m.group(1)) 
     print("\t", m.group(2)) 

Ausgang ist:

$ python test.py 
2002-03-04 with Matt 
    2002-03-04 
    Matt 
Important: 2016-01-23 with Mary 
    2016-01-23 
    Mary 
with Tom on 2015-06-30 
    2015-06-30 
    Tom 

jedoch so etwas wie das ist nicht völlig intuitiv. Ich ermutige Sie, wenn möglich mit zu versuchen.

+0

Benannte Gruppen ist groß. Danke, ich habe etwas sehr nützliches gelernt. – piRSquared

+0

Das einzige Problem mit dieser _Out-of_order_ -Methode ist, dass sie beide oder das eine oder andere mit einem fehlenden Teil übereinstimmen. Dies könnte unter Verwendung von Bedingungen mit dem Modul _regex_ geschehen, das nicht funktioniert, aber beide Teile benötigt. Es ist wirklich nicht gut auf diese Weise, es sei denn, es ist die Implikation von garantierten Teilen, oder es ist einfach nicht so wichtig. – sln

4

Wie wäre es mit 2 separaten Regex?

my_strings = [ 
    "2002-03-04 with Matt", 
    "Important: 2016-01-23 with Mary", 
    "with Tom on 2015-06-30", 
] 
import re 

pattern = r'.*(\d{4}-\d{2}-\d{2})' 
dates = [re.match(pattern, x).groups()[0] for x in my_strings] 

pattern = r'.*with (\w+).*' 
persons = [re.match(pattern, x).groups()[0] for x in my_strings] 

output = zip(dates, persons) 
print output 
## [('2002-03-04', 'Matt'), ('2016-01-23', 'Mary'), ('2015-06-30', 'Tom')] 
2

Gerade für Bildung Gründen könnte ein nicht-regex Ansatz dateutil Parser in einem „fuzzy“ Modus beinhaltet mit Daten zu extrahieren und die nltk toolkit mit den named entity recognition Namen zu extrahieren. Vollständiger Code:

import nltk 
from nltk import pos_tag, ne_chunk 
from nltk.tokenize import SpaceTokenizer 
from dateutil.parser import parse 


def extract_names(text): 
    tokenizer = SpaceTokenizer() 
    toks = tokenizer.tokenize(text) 
    pos = pos_tag(toks) 
    chunked_nes = ne_chunk(pos) 

    return [' '.join(map(lambda x: x[0], ne.leaves())) for ne in chunked_nes if isinstance(ne, nltk.tree.Tree)] 

my_strings = [ 
    "2002-03-04 with Matt", 
    "Important: 2016-01-23 with Mary", 
    "with Tom on 2015-06-30" 
] 

for s in my_strings: 
    print(parse(s, fuzzy=True)) 
    print(extract_names(s)) 

Drucke:

2002-03-04 00:00:00 
['Matt'] 
2016-01-23 00:00:00 
['Mary'] 
2015-06-30 00:00:00 
['Tom'] 

dass, obwohl wahrscheinlich ein über Komplikation ist.

Verwandte Themen