简体   繁体   English

正则表达式 / Ruby - 拆分保持分隔符

[英]Regex / Ruby - split keeping delimiter

I need to split a string containing variables/delimiters, something like;我需要拆分包含变量/分隔符的字符串,例如;

"Hello %Customer Name% your order number is %Order Number% and will be delivered soon" “您好 %Customer Name% 您的订单号是 %Order Number% 并将很快发货”

Using;使用;

string.split(/%/)
=> ["Hello ", "Customer Name", " your order number is ", "Order Number", " and will be delivered soon"]

Which is close to the requirement, but I'm trying to get to;这接近要求,但我正在努力达到;

["Hello ", "%Customer Name%", " your order number is ", "%Order Number%", " and will be delivered soon"]

So essentially I need to split at % but keep it within the returned fields.所以基本上我需要在 % 处拆分,但将其保留在返回的字段中。 I've tried a look ahead/behind with regex but cannot get it quite right.我已经尝试使用正则表达式向前/向后看,但不能完全正确。

You may use String#split with a pattern like您可以将String#split与类似的模式一起使用

/(%[^%]*%)/

According to the documentation:根据文档:

If pattern contains groups, the respective matches will be returned in the array as well.如果pattern包含组,则相应的匹配项也将在数组中返回。

See the regex demo , it matches and captures into Group 1 a % char, then any 0 or more chars other than % , and then a % .请参阅正则表达式演示,它匹配并捕获到第 1 组一个%字符,然后是除%之外的任何 0 个或更多字符,然后是一个%

See a Ruby demo :请参阅Ruby 演示

s = "Hello %Customer Name% your order number is %Order Number% and will be delivered soon"
p s.split(/(%[^%]*%)/)
# => ["Hello ", "%Customer Name%", " your order number is ", "%Order Number%", " and will be delivered soon"]

Here are three ways that could be done.以下是可以完成的三种方式。

str = "%Hello% dear %Cust Name% %your order %Order Nbr% was %lost%"

1. Use String#split 1.使用字符串#split

r = /
    (?<=     # begin positive lookbehind
      \A     # match beginning of string
      |      # or
      [ ]    # match a space
    )        # end positive lookbehind
    (?=%)    # positive lookahead asserts next char is '%'
    |        # or
    (?<=%)   # positive lookbehind asserts previous char is '%'
    (?=      # begin a positive lookahead
      [ ]    # match a space
      |      # or
      \z     # match end of string
    )        # end positive lookahead
    /x       # free-spacing regex definition mode

str.split r
  #=> ["%Hello%", " dear ", "%Cust Name%", " ", "%your%", " order ",
  #    "%Order Nbr%", " was ", "%lost%"]

2. Use String#scan 2.使用字符串#scan

r = /
    %[^%]*%       # match '%', 0+ chars other than '%', '%' 
    |             # or
    (?:           # begin non-capture group#
      (?<=\A)     # positive lookbehind asserts at beginning of string
      |           # or
      (?<=%)      # positive lookbehind asserts previous char is '%'
      (?=[ ])     # positive lookahead asserts next char is a space
    )             # end non-capture group
    [^%]*         # match 0+ chars other than '%' 
    (?=           # begin positive lookahead
      \z          # match end of string
      |           # or
      (?<=[ ])    # assert previous char is a space
      %           # match '%'
    )             # end positive lookahead
    /x            # free-spacing regex definition mode

str.scan r 
  #=> ["%Hello%", " dear ", "%Cust Name%", " ", "%your%", " order ",
  #    "%Order Nbr%", " was ", "%lost%"] 

3. Use Enumerable#slice_when 3. 使用Enumerable#slice_when

str.each_char.slice_when { |a,b|
  (a == ' ') & (b == '%') || (a == '%') & (b == ' ') }.map(&:join)
  #=> ["%Hello%", " dear ", "%Cust Name%", " ", "%your%", " order ",
  #    "%Order Nbr%", " was ", "%lost%"]    

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM