如何选择带标点符号的单词并从缩写中排除句点?

我有以下Ruby Regex选择标点符号并排除作为数字一部分的句点:

/\p{L}+|(?!\.\d)[[:punct:]]/ The profit was 5.2 thousand dollars. => The profit was thousand dollars. 

我有一个正则表达式,可以选择缩写(美国),例如:

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

The USA is located in North America

 => USA 

我想使用这些正则表达式背后的想法,以便我可以选择句子中的所有单词和标点符号,除了任何缩写中的任何句点:

 The USA is located in North America! => The USA is located in North America! 

有关如何实现这一目标的任何想法?

 str = "The USA have 50.1415 states approx and are located in North America!" str.gsub(/(? 

我认为它应该分两步完成,因为你不能将不连续的文本部分与一个匹配的迭代匹配。

使用

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

查看Ruby演示

第一步是运行带有\b(?:\p{L}\.){2,}模式的gsub (我添加了一个单词边界以确保模式只匹配1个字母的块)。 在块内,使用文字文本替换从点中去除匹配值。

第二步是在scan运行第一个正则表达式来收集所需的块。

我认为单独使用正则表达式会很困难,我很乐意通过一个有效的解决方案来纠正。

我的解决方案
首先使用第二个正则表达式解析您不想要的代码(缩写),然后使用第一个正则表达式(选择单词和标点符号)。 当您运行第一个正则表达式时,这将有效地隐藏处理的缩写。

我对项目有类似的要求。 关键是使用分区方法,遍历正则表达式(在你的情况下为2)并确保你不使用相同的正则表达式来循环中前一个正则表达式"captured"的字符串。

你可以在github: SourceParser中使用这个类,并像这样使用它:

 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 USA is located in North America") # => (The) USA (is) (located) (in) (North) (America)