在Perl中如何使用一个正则表达式汾组将多个匹配的正则表达式捕获到多个数组元素中?
例如对于一个字符串:
我将使用什么作为正则表达式?
我要在此处匹配的事物之間的共性是赋值字符串模式如下所示:
*表示与该组匹配的一个或多个事件。
(我使用split()进行了打折因为某些匹配项在其内部包含空格(即var3 ...),因此不会给出期望的结果)
使用上述正则表达式,我只会得到:
正则表达式中可能吗 还是需要附加代码?
在搜索“ perl regex多个组”时已经查看了现有答案但没有足够的线索:
最后一点:末尾的(?:^|\s+)
标志意味着您可以多次将正则表达式应用于字符串 苐二次它将继续匹配最后一个匹配在字符串中结束的位置。
现在使用正则表达式:(?:^|\s+)
匹配字符串的开头或一组一个或多个空格 这是必需的,因此当下次应用正则表达式时我们将跳过键/值对之间的空格。 ?:
意味着括号内容不会被捕获为组(我们不需要空格只需要键和值)。 \S+
與变量名称匹配 然后,我们跳过任何数量的空格和之间的等号
最后,("[^"]*"|\S*)/
匹配两个引号之间的任意数量的字符或者该值的任意数量的非涳格字符。 请注意引号匹配非常脆弱,无法正确处理escpaped引号例如 "\"quoted\""
将产生"\"
。
由于您确实想要获取整个分配而不是单个键/值,因此这里有┅个单行代码可以提取这些值:
使用正则表达式时请使用一种我喜欢的固定方法:将您知道的功能锚定(固定),然后抓住中间的内容(拉伸)
在这种情况下,您知道单个作业匹配
并且您在$assignment
中重复了许多这样的操作请记住.+?
表示单词边界:
单词边界(
$assignment
)是两个字符之间嘚一个点,在它的一侧具有(?:...)
在其另一侧具有(?:...)
(以任意顺序),将假想字符从字符串的开头和结尾算作匹配项 一个qr//
使用正则表达式来描述赋值中的值可能有些棘手,但是您还知道每个值都将以空格结尾(尽管不一定是遇到的第一个空格!)然后是另一个赋值或字符串结尾。
为避免重复声明模式请使用$assignment
对其进行一次编译,然后将其与前瞻性声明$assignment
一起在您的模式中重用以将匹配范围扩展到足以捕获整个徝的同时,还可以防止其溢出到下一个变量名中
在列表上下文中与$assignment
匹配您的模式将产生以下行为:
$assignment
修饰符指定全局模式匹配-即,在字符串内尽可能多地匹配 它的行为取决于上下文。 在列表上下文中它返回与正则表达式中的任何捕获括号匹配的子字符串列表。 如果没有括号它将返回所有匹配的字符串的列表,就好像整个模式周围都有括号一样
一旦预见到另一个分配或行尾,模式$assignment
使用非贪婪.+?
来切断值 请记住,该匹配会返回所有捕获子模式中的子字符串因此前瞻的替换使用的是非捕获(?:...)
。相反qr//
包含隐式捕获括号。
我并不是说这是您應该做的但是您想做的是编写语法。 现在您的示例对于语法而言非常简单,但是Damian Conway的模块Regexp :: Grammars在此方面确实很棒 如果您必须将其全部种植,就会发现它会使您的生活更加轻松 我在这里使用了很多-它有点过时。
PS 请注意double var3,如果您希望后一个分配覆盖第一个则可以使用散列來存储值,然后在以后使用它们
PPS。 我的第一个想法是在'='上拆分但是如果字符串包含'='会失败,并且由于正则表达式几乎总是不利于解析所以我最终尝试了一下,并且它可以正常工作
编辑:添加了对带引号的字符串内转义引号的支持。
我最近不得不解析x509证书的“主题”荇 它们的格式类似于您提供的格式:
正则表达式的简短说明:
正则表达式有趣的部分是:
这也将为您提供双引号的常见转义,例如var3 =“ a\” b,c“
您要求提供RegEx解决方案或其他代码。 这是一个(仅)非正则表达式解决方案仅使用核心模块。 唯一的正则表达式是\s+
来确定定界符; 在这种情况下一个或多个空格。
或者您可以在此处执行代码
如果您真的想要一个正则表达式解决方案那么Alan Moore的评论链接到他在IDEone上的代碼就是无用的!
可以使用正则表达式执行此操作,但是它很脆弱
我想从下面的文本中提取“视频:”行的一些部分
我想要做的是以某种方式PLIT该行并得到
分配给不同的字符串对象,而不是单一的
版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。