2017-01-19 2 views
1

Ich habe folgende Rubin Regex, die Interpunktion und schließt Perioden auswählt, die Teil Zahlen sind:Wie wählt man Wörter mit Interpunktion aus und schließt Perioden von Abkürzungen aus?

/\p{L}+|(?!\.\d)[[:punct:]]/ 

The profit was 5.2 thousand dollars. 

=> The profit was thousand dollars. 

Ich habe einen regulären Ausdruck, die Abkürzungen (U.S.A.) beispielsweise auswählen kann:

(?:[a-zA-Z]\.){2,} 

The U.S.A. is located in North America.

=> U.S.A. 

Ich mag die Ideen hinter dieser Regexes verwenden, so dass ich alle der Worte und Interpunktion in einem Satz mit Ausnahme für alle Zeiten in jeder Abkürzung wie wählen:

The U.S.A. is located in North America! 

=> The USA is located in North America! 

Alle auf Ideen Wie erreiche ich das?

+0

Das Beispiel sieht nicht ganz auf den Punkt, es sieht so aus, als ob Sie nur Abkürzungen mit Ihrer Regex finden und Punkte aus den Übereinstimmungen entfernen möchten. Oder planen Sie, ein Array der Übereinstimmungen zu erhalten und Punkte aus den Array-Elementen, die Abkürzungen sind, zu entfernen? –

+0

Ich plane, den ganzen Text und die Interpunktion zu bekommen und sie in ein Array zu setzen, das jegliche Interpunktion ('.'), Die von Abkürzungen sind, ausschließt. Ist das klarer? – chell

+0

Ja, aber ich denke, es sollte in 2 Schritten gemacht werden. Sie können diskontinuierliche Textteile nicht mit einer übereinstimmenden Iteration abgleichen. Siehe https://ideone.com/ousKNY –

Antwort

1
str = "The U.S.A. have 50.1415 states approx and are located in North America!" 
str.gsub(/(?<!\p{L}\p{L})\P{L}*\.[^\p{L}\s]*/, '').squeeze 
#⇒ "The USA have states aprox and are located in North America!" 
+0

Gibt es eine Möglichkeit, das Ergebnis wie folgt in ein Array aufzuteilen: ["The", "USA", "have", "states", "aprox", "and", "sind", "located", "in", "Nord", "Amerika", "!"] und passen die Periode auch in eine Abkürzung wie Dr. – chell

+0

'str.gsub (/ (? mudasobwa

+0

Ihre Antwort funktioniert sehr gut für meine aktuelle Anwendung. Ich werde Ihrem Rat folgen und auch in Lex/Yacc schauen. Vielen Dank. – chell

0

Ich denke, mit Regex allein wird schwierig sein, ich werde froh sein, mit einer funktionierenden Lösung korrigiert werden.

Meine Lösung:
den Code analysieren, die Sie nicht wollen (die Abkürzungen) Ihre zweite Regex zuerst, und verwenden Sie dann die erste regex (wählt Worte und Interpunktion). Dadurch werden die Abkürzungen für die Verarbeitung beim Ausführen der ersten Regex-Datei effektiv ausgeblendet.

Ich habe eine ähnliche Anforderung für ein Projekt. Der Schlüssel ist, die Methode partition zu verwenden, durchlaufen Sie die regulären Ausdrücke (in Ihrem Fall 2) und stellen Sie sicher, dass Sie nicht die gleiche Regex für die Zeichenfolge verwenden, die "captured" von der vorherigen Regex in der Schleife war.

können Sie diese Klasse von Github verwenden: SourceParser und es wie folgt verwendet werden:

parser = SourceParser.new 
parser.regexter('abbrs', /(?:[a-zA-Z]\.){2,}/) # return matched as is 
parser.regexter(
    'first regex', 
    /\p{L}+|(?!\.\d)[[:punct:]]/, 
    lambda do |token, regexp| 
     "(#{token})" 
    end 
) 
parser.parse("The U.S.A. is located in North America") 
# => (The) U.S.A. (is) (located) (in) (North) (America) 
3

Ich denke, es sollte in zwei Schritten durchgeführt werden, da Sie nicht diskontinuierliche Textteile mit einer passenden Iteration mithalten können.

Verwenden

s = 'The U.S.A. is located in North America!' 
s = s.gsub(/\b(?:\p{L}\.){2,}/) { $~[0].gsub(".", "") } 
puts s.scan(/\p{L}+|(?!\.\d)[[:punct:]]/) 

Siehe Ruby demo

Der erste Schritt gsub mit dem \b(?:\p{L}\.){2,} Muster laufen ist (Ich habe eine Wortgrenze um sicherzustellen, dass nur das Muster 1 Buchstaben Chunks entspricht). Innerhalb des Blocks wird der Übereinstimmungswert von Punkten entfernt, indem eine literale Textersetzung verwendet wird.

Der zweite Schritt ist die erste Regex innerhalb einer scan, um die Chunks zu sammeln, die Sie brauchen.

+0

Das funktioniert. Ich habe auch die Antwort von Mudasobwa ausprobiert, da sie dasselbe in einer Zeile erreicht. – chell

+0

Wiktor gibt es einen Weg, um Ihre Regex den Zeitraum in Dr. – chell

+0

zu erkennen Dies könnte ein Fall sein, wenn Sie alle Abkürzungen in einem Schritt behandeln möchten. [Dieser Abschnitt, der die Ruby-Bibliothek aufspaltet] (https://github.com/apohlo/srx-english/blob/master/lib/srx/english/sentence_splitter.rb) enthält einige nette Regexps. Siehe [dieser, um viele Abkürzungen zu behandeln] (http://rubular.com/r/F9ytXwKb82). –

Verwandte Themen