如何获得角色前后的所有单词?

时间:2011-06-29 21:28:55

标签: ruby regex

我从来没有在今天之前尝试过正则表达式,到目前为止我喜欢它,但是我迷失了一些东西。

我有一个看起来像这样的字符串:

Type OtherType ThirdType - SubType AnotherSubType QuiteTheType

我想要两个正则表达式,都关心'-'字符 首先,我希望在该角色之前的所有单词,然后是在它之后的所有单词我将使用Ruby的gsub将它们转换为一个字符串数组,两个数组,这就是为什么我需要两个正则表达式。

到目前为止,我有这个:([a-zA-z]{1,}) (?=-)但是这只能让我在破折号之前得到正确的信息,I.E。 ThirdType。 如果我只是使用([a-zA-z]{1,}),我会突出显示所有单词,但其中包含-之后我不想要的单词。

我怎样才能在[a-zA-z]{1,}之前发生-的所有事件,但不一定在它之前发生?

4 个答案:

答案 0 :(得分:2)

s = "Type OtherType ThirdType - SubType AnotherSubType QuiteTheType"

words_before, words_after = s.split(/\s*-\s*/).map do |t|
  t.split(/\s+/)
end
p words_before    # => ["Type", "OtherType", "ThirdType"]
p words_after     # => ["SubType", "AnotherSubType", "QuiteTheType"]

以下是其工作原理:

s.split(/\s*-\s*/)

使用正则表达式分隔符将字符串拆分为两个。分隔符的意思是“任何数量的空白区域,然后是破折号,然后是任何数量的空白区域”。结果是一个包含两个字符串的数组:分隔符左侧的部分和右侧的部分。

...map do |t|
  ...
end

map采用数组并将其转换为具有相同数量元素的另一个数组。它接受数组的每个元素,将其传递给块,并使用块中的返回值作为该元素的新值。我们将使用它将两个字符串转换为两个单词数组。

那么,街区里有什么?

t.split(/\s+/)

这是另一个分裂。这次我们将拆分一个或多个空白字符。这导致了一系列单词。

由于地图将该分割首先应用于左侧,然后是右侧,因此整个s.split...表达式的结果是两个数组的数组。

现在我们将使用Ruby的一种有趣的语法:

words_before, words_after = s.split...

每当在赋值的左侧有多个变量时,ruby将“分解”右侧的数组,将数组的第一个元素赋值给第一个变量,将数组的第二个元素赋值给第二个变量, 等等。由于我们的数组有两个元素(第一个是左侧的单词数组,第二个是右侧的单词数组),我们将使用两个变量来保存它们。

答案 1 :(得分:1)

我不确切知道Ruby的正则表达式实现是如何工作的,但是Perl中的以下正则表达式可以为您提供所需的内容:

/^([a-zA-z\s]+) \- ([a-zA-Z\s]+)$/

例如:

perl -e '$_="Type OtherType ThirdType - SubType AnotherSubType QuiteTheType";
if(/^([a-zA-z\s]+) \- ([a-zA-Z\s]+)$/){print "$1\n";print "$2\n";}'

产生

Type OtherType ThirdType
SubType AnotherSubType QuiteTheType

ETA:为了解释发生了什么,初始^表示行的开头,结尾$表示行的结尾。所以,^([a-zA-Z\s]+)从头开始,(贪婪)匹配从行开头到破折号前面的所有单词(由反斜杠转义,因为-是保留的大多数正则表达式实现中的字符)。与([a-zA-Z\s]+)$一样。

答案 2 :(得分:1)

您可以使用预测:

(\w+)(?=.*?-)

答案 3 :(得分:1)

虽然正则表达式功能强大且有用,但它通常会导致比您需要的更复杂的解决方案,并且会导致更多的工作和维护。

sentence = 'Type OtherType ThirdType - SubType AnotherSubType QuiteTheType'

sentence.split('-') # => ["Type OtherType ThirdType ", " SubType AnotherSubType QuiteTheType"]
sentence.scan(/[^-]+/) # => ["Type OtherType ThirdType ", " SubType AnotherSubType QuiteTheType"]

如果连字符周围的空格很烦人,则通过strip传递返回的部分:

sentence.split('-').map{ |w| w.strip } # => ["Type OtherType ThirdType", "SubType AnotherSubType QuiteTheType"]
sentence.scan(/[^-]+/).map{ |w| w.strip } # => ["Type OtherType ThirdType", "SubType AnotherSubType QuiteTheType"]

如果你想要单词,而不是连字符前后的句子:

sentence.split('-').map{ |w| w.strip.split(' ') } # => [["Type", "OtherType", "ThirdType"], ["SubType", "AnotherSubType", "QuiteTheType"]]
sentence.scan(/[^-]+/).map{ |w| w.strip.split(' ') } # => [["Type", "OtherType", "ThirdType"], ["SubType", "AnotherSubType", "QuiteTheType"]]