如何选择带标点符号的单词并从缩写中排除句点?
我有以下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)