2016-04-10 5 views
2

Ich versuche, nur gültige Prozentangaben zu extrahieren und jede falsche Darstellung aus einer Zeichenfolge mit regulären Ausdruck in Python zu entfernen. Die Funktion sollte so funktionieren, DennExtrahieren Sie nur prozentuale Informationen aus Text in Python mithilfe von Regex

0-100% = TRUE 
0.12% = TRUE 
23.1245467% = TRUE 
9999% = FALSE 
8937.2435% = FALSE 
7.% = FALSE 

ich ein paar Lösungen in Stack-Überlauf überprüft haben, die nur 0-100% extrahieren. Ich habe die folgenden Lösungen versucht,

('(\s100|[123456789][0-9]|[0-9])(\.\d+)+%') 
'(\s100|\s\d{1,2})(\.\d+)+%' 
'(\s100|\s\d[0-99])(\.\d+)+%' 

Alle diese Werke für alle anderen Möglichkeiten außer 0-99% (gibt FALSCH) und 12411,23526% (gibt TRUE). Der Grund für den Platz ist, dass ich nur zwei Ziffern extrahieren möchte.

+0

Was die Logik hinter dem Wunsch Ausgänge ist? – Kasramvd

+0

Was sollte 23.123456-45.842% bewerten? – mwm314

+0

@Kasramvd, Möchten Sie Prozentwerte in einem bestimmten Satz identifizieren. – psun

Antwort

0

In Anbetracht aller Möglichkeiten folgende Regex funktioniert.

Wenn Sie einfach die ?: ignorieren, d. H. Nicht einfangende Gruppe Regex ist nicht so einschüchternd.

Regex:^(?:(?:\d{1,2}(?:\.\d+)?\-)?(?:(?:\d{1,2}(?:\.\d+)?)|100))%$

Erläuterung:

  • (?:(?:\d{1,2}(?:\.\d+)?\-)? Streichhölzer untere Grenze, wenn es eine ist, wie im Fall von 0-100% mit optionalen Dezimalteil.

  • (?:(?:\d{1,2}(?:\.\d+)?)|100) entspricht der oberen Grenze oder wenn nur einzelne Zahl mit der Grenze von 100 mit optionalem Dezimalteil.

Regex101 Demo


Eine andere Version der gleichen Regex für solche Vorkommnisse innerhalb der String-Matching den Anker ^ und $ und prüfen, ob nicht-Ziffern am Anfang zu entfernen wäre.

Regex:(?<=\D|^)(?:(?:\d{1,2}(?:\.\d+)?\-)?(?:(?:\d{1,2}(?:\.\d+)?)|100))%

Regex101 Demo

1

figured it out. Das Problem lag in '+' in dem Ausdruck '(\.\d+)+', während es '(\.\d+)*' hätte sein sollen. Der erste Ausdruck erwartet Dezimalwerte für zweistellige Prozentwerte, während der zweite nicht. Meine endgültige Version ist unten angegeben.

'\s(100|(\d{1,2}(\.\d+)*))%' 

Sie können zu Beginn eines Satzes \s mit $ für Prozentwerte ersetzen. Außerdem haben die Versionen in meinem Fragenbereich Dezimalwerte für 100 akzeptiert, was ein ungültiger Prozentwert ist.

+0

'*' ist nicht die richtige Wahl für 'optionale' Dezimalwerte. Wie auch immer '0-100%'? –

+0

@noob, 0 wird auf '\ d {1,2}' und 100 auf die '100' am Anfang der Regex geachtet. Dieser Ausdruck adressiert meine Testfälle. Wenn Sie der Meinung sind, dass ein gültiger prozentualer Testfall vorliegt, für den dies nicht funktioniert, lassen Sie es mich wissen. – psun

0

Ich würde mich nicht auf Regex allein verlassen - es ist nicht gemeint, um Bereiche in erster Linie zu filtern.
bessere Optik für die Kandidaten in der Zeichenfolge und analysieren sie programmatisch danach, etwa so:

import re 

string = """ 
some gibberish in here 0-100% = TRUE 
some gibberish in here 0.12% = TRUE 
some gibberish in here 23.1245467% = TRUE 
some gibberish in here 9999% = FALSE 
some gibberish in here 8937.2435% = FALSE 
some gibberish in here 7.% = FALSE 
""" 

numbers = [] 
# look for -, a digit, a dot ending with a digit and a percentage sign 
rx = r'[-\d.]+\d%' 

# loop over the results 
for match in re.finditer(rx, string): 
    interval = match.group(0).split('-') 
    for number in interval: 
     if 0 <= float(number.strip('%')) <= 100: 
      numbers.append(number) 

print numbers 
# ['0', '100%', '0.12%', '23.1245467%']