Regex练习,解析一个意外出错的字符串



我有一个字符串

str = (größen xs-xxl)s+m+l+xl+xxl+xxxl(Solid-Farben)Dark Grey (2890)+Black (9000)+Mocca (5050)+Cognac (5048)

由四部分组成:

1: (größen xs-xxl)
2: s+m+l+xl+xxl+xxxl
3: (Solid-Farben)
4: Dark Grey (2890)+Black (9000)+Mocca (5050)+Cognac (5048)

最初,字符串描述颜色和大小的变化,并且总是以相同的方式组合在一起:

1)第一个键(尺寸或颜色类别的名称,这次括号中的"grßen xs xxl"
2)第一个键的值,用加号分隔
3)括号中的第二个键(这次"Solid Farben"
4)第二个键的值,用加号分隔。不幸的是,值字符串中也有空格和圆括号。

所有零件都是简单地粘在一起的,我的工作就是对这些东西进行逆向工程
到目前为止,我已经在构思这个正则表达式时考虑到了以下想法:

首先,我需要括号内的密钥名称,所以把所有内容都放在括号内:

(([^+)]+))

由于这也捕获了属于第二个键的值的括号内的数字(例如(2890),因此第二部分是对结束括号后的加号或行尾进行的否定前瞻断言测试。

(?!+|$)

这些放在一起捕获了我字符串的关键组件:

regex = /(([^+)]+))(?!+|$)/
1.9.3-p374 :085 > str.scan regex
=> [["(größen xs-xxl)"], ["(Solid-Farben)"]] 

现在,我正不顾一切地试图提取相应的值。当然,我可以迭代键数组,拆分源字符串并处理收集到的结果,但这非常难看
一种更优雅的方法是将正则表达式加倍,并在两者之间添加(.+)以获得尾部值部分:

regex = (([^+)]+))(?!+|$)(.+?)(([^+)]+))(.+?)$
1.9.3-p374 :096 > str.scan regex
=> [["(größen xs-xxl)", "s+m+l+xl+xxl+xxxl", "(Solid-Farben)", "Dark Grey (2890)+Black (9000)+Mocca (5050)+Cognac (5048)"]] 

,这正是我想要的。但是,尽管这个解决方案几乎和后处理第一个正则表达式一样丑陋,但它没有考虑到可能还有第三个键,也有相应的值,也添加到原始字符串中:

1: (größen xs-xxl)
2: s+m+l+xl+xxl+xxxl
3: (Solid-Farben)
4: Dark Grey (2890)+Black (9000)+Mocca (5050)+Cognac (5048)
5: (NEW DIMENSION)
6: V-NECK+O-NECK+SIZE(tall)+SIZE(short)
str2 = (größen xs-xxl)s+m+l+xl+xxl+xxxl(Solid-Farben)Dark Grey (2890)+Black (9000)+Mocca (5050)+Cognac (5048)(NEW DIMENSION)V-NECK+O-NECK+SIZE(tall)+SIZE(short)

这在各个方面都有所突破,因为我现在需要三个捕获。当然,我最初的regex只设计为匹配两次出现,但如果我不知道有多少部分是"粘在一起"的呢?

一个比我脑子大的人能启发我吗?我希望看到这一点更加优雅,并作为一个额外的功能,在"粘合在一起"到源字符串之前,将其扩展到无限次(甚至只有一次)的原始部分。(:

您可以尝试以下string.scan函数。

> str = "(größen xs-xxl)s+m+l+xl+xxl+xxxl(Solid-Farben)Dark Grey (2890)+Black (9000)+Mocca (5050)+Cognac (5048)(NEW DIMENSION)V-NECK+O-NECK+SIZE(tall)+SIZE(short)"
> str.scan(/([^()]*).*?(?=((?![wd]+))[^)]*)|$)/)
=> ["(größen xs-xxl)s+m+l+xl+xxl+xxxl", "(Solid-Farben)Dark Grey (2890)+Black (9000)+Mocca (5050)+Cognac (5048)", "(NEW DIMENSION)V-NECK+O-NECK+SIZE(tall)+SIZE(short)"]
> str.scan(/(([^()]*))(.*?)(?=((?![wd]+))[^)]*)|$)/)
=> [["(größen xs-xxl)", "s+m+l+xl+xxl+xxxl"], ["(Solid-Farben)", "Dark Grey (2890)+Black (9000)+Mocca (5050)+Cognac (5048)"], ["(NEW DIMENSION)", "V-NECK+O-NECK+SIZE(tall)+SIZE(short)"]]

相关内容

最新更新