正则表达式得到最后一次出现前后的所有内容
我正在尝试构造一个正则表达式,它会在最后一次出现的数字前后分割。我希望得到:正则表达式得到最后一次出现前后的所有内容
"index100.html" # => ["index", "100", ".html"]
"page.php?id=100" # => ["page.php?id=", "100", ""]
"page.php?f=5&page=295" # => ['page.php?f=5&page=', 295, '']
这里是我想出了正则表达式:
regex = /([^0-9]+|^)(\d+?)([^0-9]+|$)/
它适用于前两个例子,但不是最后一个。我得到结果:
["page.php?f=", 5, "&page="]
如何修改正则表达式使其工作的第三种情况?
您可以充分利用.*
贪婪的匹配,但与负回顾后(?<!\d)
遏制它,以确保您的数字去年整块匹配:
/(.*)(?<!\d)(\d+)(.*)/
^^^^^^^^^^^
见regex demo。或者,您可以在开始和结束处添加\A
和\z
锚。
详细:
-
(.*)
- 除换行符以外,尽可能多的,0个或多个字符匹配到最后一个 -
(?<!\d)(\d+)
- 这是之前没有以数字1 +数字 -
(.*)
- 该行的其余部分。
要匹配换行符,请在最后一个正则表达式分隔符后面添加m
修饰符。
鉴于第一个段不应该为空,您可以将非数字作为第一个段的最后一部分。 – sawa
@sawa:我在这里依靠回溯,它应该做得很好。当我开始复杂化模式时,人们通常会大喊大叫。 –
另一种方式没有向后看。
((?:\d*\D)*)(\d+)(.*)
另一个没有回顾后
(这仅仅是尽可能快地使用回顾后
,但如果你没有它,像JS,这样效果更好)
(.*(?:\D|^))(\d+)(.*)
这里假定除了最后一个号码以外的号码不能有多个数字。我不认为这是一个安全的假设。如何用'*'替换'?'? –
@TimPietzcker - 修正.. – sln
这两个正则表达式是不等效的:第二个需要在数字之前的至少一个字符,或数量必须在该行的开头。这就是为什么我不会比较表现。 –
"index100.html"
.partition(/\d+(?=\D*\z)/) # => ["index", "100", ".html"]
"page.php?id=100"
.partition(/\d+(?=\D*\z)/) # => ["page.php?id=", "100", ""]
"page.php?f=5&page=295"
.partition(/\d+(?=\D*\z)/) # => ["page.php?f=5&page=", "295", ""]
虽然代码经常为自己说话,但最好向代码添加一些解释。这会在审查队列中弹出,因为只有代码的答案倾向于。 – Will
def split_it(str)
str.reverse.partition(/\d+/).reverse.map(&:reverse)
end
split_it "index100.html"
#=> ["index", "100", ".html"]
split_it "page.php?id=100"
#=> ["page.php?id=", "100", ""]
split_it "page.php?f=5&page=295"
#=> ['page.php?f=5&page=', 295, '']
是0
为
str = "page.php?f=5&page=295"
的步骤如下:(。*)
s = str.reverse
#=> "592=egap&5=f?php.egap"
a = s.partition(/\d+/)
#=> ["", "592", "=egap&5=f?php.egap"]
b = a.reverse
#=> ["=egap&5=f?php.egap", "592", ""]
b.map(&:reverse)
#=> ["page.php?f=5&page=", "295", ""]
尝试此'(。*)(\ d +)(。*)' – sln
的['(\ d +) (。*)'](http://rubular.com/r/orRN2ecoQk)将不起作用。 –
为什么不是哥们?你说的对,我的错。 – sln