2016-03-26 10 views
0

Ich habe eine Zeichenfolge, die ein Wort und mehrere Zahlen hat. Ich möchte die Zeichenfolge nach dem Wort partitionieren. Zum BeispielGreifen Sie das ganze Wort zwischen den Ziffern

"100 1990 top 1000 500" #=> ["100 1990 ", "top", " 1000 500"] 

dachte ich, dass dies funktionieren würde, aber es funktioniert nicht:

'100 1990 top 1000 500'.partition(/[\ba-zA-Z\b]/) # => ["100 1990 ", "t", "op 1000 500"] 

jedoch mit Rubular, die Regex über das ganze Wort überein "top" (und nur dieses Wort) gegeben die obige Zeichenfolge.

Was fehlt mir?

+0

versuchen Sie, Split-Methode auf Zeichenfolge zu verwenden. – Ilya

+0

'/ [\ ba-zA-Z \ b] /' ist falsch. Du würdest '/ \ b [a-zA-Z] \ b /' wollen. –

+0

@theTinMan, du hast '+' vergessen und ich glaube nicht, dass du willst, dass das Wort bricht. –

Antwort

0

In diesem speziellen Beispiel gibt es keine Notwendigkeit, einen regulären Ausdruck zu verwenden, die in der Regel langsamer sind im Vergleich zu einfachen String-Methoden:

split tut genau das, was Sie brauchen:

'1990 top 1000'.split 
#=> ["1990", "top", "1000"] 

Wenn Sie in die interessiert sind,

'1990 top 1000'.split('top') 
#=> ["1990 ", " 1000"] 

: String auf jeder Seite des Wortes, könnte man dieses Wort als Argument an split verwenden möchten Oder einfach nur diese regexp verwenden:

'1990 top 1000'.partition /\b[a-zA-Z]+\b/ 
#=> ["1990 ", "top", " 1000"][ 

Als Wiktor diese regexp erwähnt würde Zeichen nicht übereinstimmen, die nicht in dem A-Z-Bereich ist. Um auch Unicode-Zeichen wie Ä, ß übereinstimmen oder ç möchten Sie vielleicht die [[:alpha:]] Zeichenklasse verwenden:

'1990 äop 1000'.partition /\b[[:alpha:]]+\b/ 
#=> ["1990 ", "äop", " 1000"] 

Lesen Sie mehr über Regexp character classes.

+0

Danke für die Antwort, aber ich brauche eine Partition. Ich möchte die Teilstrings auf jeder Seite des Wortes trennen. – sarkon

+0

Aber ich weiß nicht, dass das Wort "top" sein wird. Ich weiß nur, dass es ein (ganzes) Wort mit Ziffern auf beiden Seiten geben wird. – sarkon

+0

Super! Ich muss Regex lernen. Bleibt noch die Frage, warum es in Rubular nicht funktioniert hat. Gibt es einen besseren Ruby Regexp Editor? – sarkon

0

Ihre regex entsprechen genau ein Symbol, entweder \b (Backspace es keine Wortgrenze ist, weil \b innerhalb einer Zeichenklasse seiner besonderer Bedeutung verliert und nur eine Escape-Sequenz) oder ein ASCII-Buchstaben (ein von a-z oder A-Z Bereiche). Rubular.com hat also 3 separate Treffer angezeigt. Sie können dies selbst überprüfen, indem Sie eine Erfassungsgruppe über Ihrem Muster platzieren (siehe your regex demo).

Sie /\p{L}+/ regex verwenden (das entspricht 1 oder mehr Buchstaben) mit partition:

'1990 top 1000'.partition(/\p{L}+/) 

Siehe IDEONE demo

Wenn die Saiten nur 1 Wort enthalten, sollte diese Arbeit. BTW, \p{L} entspricht jedem Unicode-Buchstaben, nicht nur ASCII.

0

Es ist schwierig zu beantworten, was Sie "fehlen", aber was Sie wahrscheinlich missverstehen, ist der Zeichenbereich [] in Regex. Es drückt ein einzelnes Zeichen aus. [\ba-zA-Z\b] bedeutet entweder eine Wortgrenze, einen kleinen Buchstaben oder einen großen Buchstaben (oder redundant, eine Wortgrenze). Sie partitionieren durch ein einzelnes solches Zeichen, was nicht das ist, was Sie wollen.

+0

Siehe @ Wiktors Kommentare zur Behandlung von '\ b' innerhalb einer Zeichenklasse. Zum Beispiel "abc def" .partition ([/ \ b /]) # => ["abc def", "", ""] ', was der Rückgabewert ist, den Sie erhalten, wenn auf Partition keine Übereinstimmung gefunden wird Argument. Und was ist '\ b'? 'puts" cats \ b und dogs "# => cat and dogs'. –

+0

@CarySwoveland Sie meinen '/ [\ b] /', denke ich. Und '\ b' hat keine Bedeutung in einer Zeichenkette. Es ist sinnvoll in einer Regex. – sawa

+0

Ja, ich meinte '/ [\ b] /'. Wahr, es hat eine besondere Bedeutung in einer Regex, vorausgesetzt es ist nicht in einer Zeichenklasse. '\ b' in einer Schnur war eine Seite. '" \ b ".ord # => 8' (" Rücktaste "). Das war neu für mich (oder ist etwas, was ich vergessen habe). –

Verwandte Themen