Ruby正则表达式分裂字符串

时间:2013-10-18 16:42:21

标签: ruby-on-rails ruby regex ruby-on-rails-3 split

首先,我对正则表达式的了解并不是那么好。我个人将他们与哈利波特的书中的伏地魔相提并论。

我试图使用正则表达式将相当大的字符串拆分为块。

字符串就像(你可能想看到它):

Hi {{company_name}}\r\n\r\nA new order has been created via your website, from a customer with the following details:\r\n\r\n<table border=\"1\">\r\n  <tr>\r\n    <td>Full Name</td>\r\n    <td>{{ customer.full_name }}</td>\r\n  </tr>\r\n  <tr>\r\n    <td>Email</td>\r\n    <td>{{ customer.email }}</td>\r\n  </tr>\r\n  <tr>\r\n    <td>Mobile</td>\r\n    <td>{{ customer.mobile }}</td>\r\n  </tr>\r\n  <tr>\r\n    <td>Landline</td>\r\n    <td>{{ customer.landline }}</td>\r\n  </tr>\r\n  <tr>\r\n    <td>Notes</td>\r\n    <td>{{ notes }}</td>\r\n  </tr>\r\n</table>\r\n\r\nThese products or services were ordered:\r\n\r\n{% if appointment_items != empty %}\r\nBooking Details\r\n<table border=\"1\">\r\n  <tr>\r\n   <td>Type</td>\r\n   <td>Description</td>\r\n   <td>Price</td>\r\n</tr>\r\n{% for line_item in appointment_items %}\r\n<tr>\r\n  <td>{{ line_item.category }}</td>\r\n  <td>{{ line_item.short_description}}</td>\r\n  <td>{{ line_item.price | display_price }}</td>\r\n</tr>\r\n{% endfor %}\r\n</table>\r\n{% endif %}\r\n\r\n{% if enquiry_items != empty %}\r\nEnquiry Details\r\n<table border=\"1\">\r\n  <tr>\r\n   <td>Type</td>\r\n   <td>Description</td>\r\n   <td>Price</td>\r\n</tr>\r\n{% for line_item in enquiry_items %}\r\n<tr>\r\n  <td>{{ line_item.category }}</td>\r\n  <td>{{ line_item.short_description}}</td>\r\n  <td>{{ line_item.price | display_price }}</td>\r\n</tr>\r\n{% endfor %}\r\n</table>\r\n{% endif %}\r\n\r\n{% if has_appointment %}\r\n\r\nOne or more of the order items requires an engineer appointment. This appointment has been allocated to an engineer and given a provisional appointment time.\r\n\r\n<table border=\"1\">\r\n  <tr>\r\n    <td>Start</td>\r\n    <td>{{ appointment.start | date_with_time_zone: \"%A %d %b %Y at %H:%M %P\"  }}</td>\r\n  </tr>\r\n  <tr>\r\n    <td>Finish</td>\r\n    <td>{{ appointment.finish | date_with_time_zone: \"%A %d %b %Y at %H:%M %P\"  }}</td>\r\n  </tr>\r\n  <tr>\r\n    <td>Duration</td>\r\n    <td>{{ appointment.duration }}</td>\r\n  </tr>\r\n  <tr>\r\n    <td>Engineer Name</td>\r\n    <td>{{ appointment.engineer }}</td>\r\n  </tr>\r\n</table>\r\n\r\nThe address of the appointment is:\r\n\r\n<table border=\"1\">\r\n  <tr>\r\n    <td>Address Line 1</td>\r\n    <td>{{ appointment.address.line_one }}</td>\r\n  </tr>\r\n  <tr>\r\n    <td>Address Line 2</td>\r\n    <td>{{ appointment.address.line_two }}</td>\r\n  </tr>\r\n  <tr>\r\n    <td>Town/City</td>\r\n    <td>{{ appointment.address.town_city }}</td>\r\n  </tr>\r\n  <tr>\r\n    <td>County</td>\r\n    <td>{{ appointment.address.county }}</td>\r\n  </tr>\r\n  <tr>\r\n    <td>Postcode</td>\r\n    <td>{{ appointment.address.postcode }}</td>\r\n  </tr>\r\n</table>\{% endif %}

因此,此字符串是存储在数据库中的电子邮件,然后使用液体标签进行解析。

液体是一种诱人的语言。它具有以下变量的概念:{{ var_name }}和逻辑,例如if语句,如:{% if var_name == true %} //do something {% endif %}

我需要能够在发送时获得100%将在此电子邮件中发送的最长字符串。我的最终目标是编写一个测试,检查电子邮件正文中最长的字符串。

我想出了这个:

regex = /{{.*?}}|\\\n|\\\r|({%\s?if).*(endif\s?%})/

mail_template_content_part = @mail_template.content.split(regex).reject(&:empty?).map(&:strip).max_by(&:length)

正则表达式分裂液体变量{{ my_var }}新行,以及{% if的开头以及最后结束的所有内容endif %}

我喜欢max_by方法:D

现在每个选项都可以单独使用。但是当它们全部放在一起时它们似乎不起作用。我不确定到底发生了什么,我的怀疑是分裂正在分裂,因此正则表达式的if / end部分没有运行。

所以我的问题是

正则表达式有什么问题?

如何使用正则表达式进行拆分?

我能以正确的方式解决这个问题吗?

谢谢,

迪基

1 个答案:

答案 0 :(得分:0)

Hmhmmm,使用正则表达式解析语言只是一个拐杖......

Liquid本身使用大量的正则表达式。他们最近将其更改为使用真正的解析器。

我认为使用自定义Liquid标签或自定义HTML标记,ID或类来注释应该放入电子邮件的部分可能是更好的主意。