我有以下Ruby Regex选择标点符号并排除作为数字一部分的句点:
/\p{L}+|(?!\.\d)[[:punct:]]/
The profit was 5.2 thousand dollars.
=> The profit was thousand dollars.
我有一个正则表达式可以选择缩写(U.S.A),例如:
(?:[a-zA-Z]\.){2,}
The U.S.A. is located in North America
。
=> U.S.A.
我想使用这些正则表达式背后的想法,以便我可以选择句子中的所有单词和标点符号,除了任何缩写中的任何句点:
The U.S.A. is located in North America!
=> The USA is located in North America!
关于如何实现这一目标的任何想法?
答案 0 :(得分:3)
我认为应该分两步完成,因为你不能将不连续的文本部分与一个匹配的迭代匹配。
使用
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:]]/)
请参阅Ruby demo
第一步是使用gsub
模式运行\b(?:\p{L}\.){2,}
(我添加了一个单词边界以确保模式只匹配1个字母的块)。在块中,使用文字文本替换从点中去除匹配值。
第二步是在scan
内运行你的第一个正则表达式来收集你需要的块。
答案 1 :(得分: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!"
答案 2 :(得分:0)
我认为单独使用正则表达式会很困难,我很乐意通过一个有效的解决方案来纠正。
我的解决方案:
首先使用第二个正则表达式解析您不想要的代码(缩写),然后使用第一个正则表达式(选择单词和标点符号)。这将有效地隐藏运行第一个正则表达式时的处理缩写。
我对项目有类似的要求。关键是使用partition方法,遍历正则表达式(在你的情况下为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 U.S.A. is located in North America")
# => (The) U.S.A. (is) (located) (in) (North) (America)