如何使用正则表达式来匹配“stuff = foo”'stuff'='stuff''more stuff'形式的内容

时间:2010-05-27 02:19:00

标签: regex

我需要一个正则表达式来匹配这样的东西,

'text'| 'text'| ...... | 'text'(~text)='text'| 'text'| ...... | '文本'

我只想把它分成两部分,等号左边的部分和右边的部分。但是,任何'text'条目在'characters'之间都可以有“=”。我想要尝试匹配偶数个后跟a =,但我不确定如何匹配偶数个东西..还要注意我不知道两边有多少条目可能有。几个例子,

'51NL9637X33'| 'ISL6262ACRZ-T'| 'QFN'(~51NL9637X33)='51NL9637X33'| 'ISL6262ACRZ-T'| 'INTERSIL'| 'QFN7SQ-HT1_P49'| '()'

应该提取, '51NL9637X33'| 'ISL6262ACRZ-T'| 'QFN'(〜51NL9637X33) 和, '51NL9637X33'| 'ISL6262ACRZ-T'| 'INTERSIL'| 'QFN7SQ-HT1_P49'| '()'

'227637'| 'SMTU2032_1'| 'SKT W / BAT'(~227637)='227637'| 'SMTU2032_1'| 'RENATA'| 'SKT28_5X16_1-HT5_4_P2'| '()':SPECIAL_A ='BAT_CR2032',PART_NUM_A ='202649'

应该提取,  '227637'| 'SMTU2032_1'| 'SKT W / BAT'(~227637) 和, '227637'| 'SMTU2032_1'| 'RENATA'| 'SKT28_5X16_1-HT5_4_P2'| '()':SPECIAL_A ='BAT_CR2032',PART_NUM_A ='202649'

另请注意,第一部分末尾的小tilda位是可选的,所以我不能只是寻找它。

3 个答案:

答案 0 :(得分:4)

实际上我根本不会使用正则表达式。假设您的语言有split操作,我首先拆分|字符以获取以下列表:

'51NL9637X33'
'ISL6262ACRZ-T'
'QFN'(~51NL9637X33) = '51NL9637X33'
'ISL6262ACRZ-T'
'INTERSIL'
'QFN7SQ-HT1_P49'
'()'

然后我会在=字符上拆分每个字符以获取密钥和(可选)值:

'51NL9637X33'           <null>
'ISL6262ACRZ-T'         <null>
'QFN'(~51NL9637X33)     '51NL9637X33'
'ISL6262ACRZ-T'         <null>
'INTERSIL'              <null>
'QFN7SQ-HT1_P49'        <null>
'()'                    <null>

您尚未指定为什么您认为正则表达式是正确的工具,但大多数现代语言也具有split功能,并且正则表达式不一定是每个人的答案要求。

答案 1 :(得分:0)

我同意paxdiablo的说法,正则表达式可能不是最适合此任务的工具,具体取决于您使用的语言。

问题“如何匹配偶数个字符?”尽管如此,这很有意思,以下是我在你的案例中如何做到这一点:

(?:'[^']*'|[^=])*(?==)

此表达式通过在当前位置查找'来匹配条目的左侧部分。如果找到一个,它会前进到下一个',从而只匹配偶数个引号。如果找不到',则它匹配任何不等号的符号,然后确保匹配的字符串后面有一个等号。它的工作原理是因为正则表达式引擎从左到右评估OR结构。

您可以使用

在两个捕获组中获取左右部分
((?:'[^']*'|[^=])*)=(.*)

我建议使用http://gskinner.com/RegExr/来修改正则表达式。 =)

答案 2 :(得分:0)

正如paxdiablo所说,你几乎肯定不想在这里使用正则表达式。 split建议并不错;我自己可能会在这里使用解析器 - 有很多结构可供使用。这里的想法是你正式指定你所拥有的语法 - 有点像你给我们的,只是严谨的。因此,例如:field是由单引号括起来的一系列非单引号字符; fields是由空格分隔的任意数量的field|,以及更多的空白区域; tilde是由(~)包围的非右括号字符; exprfields,可选空格,可选tilde=,可选空格和其他fields。您如何表达这取决于您使用的语言。例如,在Haskell中,使用Parsec库,您可以按如下方式编写每个解析器:

import Text.ParserCombinators.Parsec

field :: Parser String
field = between (char '\'') (char '\'') $ many (noneOf "'\n")

tilde :: Parser String
tilde = between (string "(~") (char ')') $ many (noneOf ")\n")

fields :: Parser [String]
fields = field `sepBy` (try $ spaces >> char '|' >> spaces)

expr :: Parser ([String],Maybe String,[String])
expr = do left <- fields
          spaces
          opt  <- optionMaybe tilde
          spaces >> char '=' >> spaces
          right <- fields
          (char '\n' >> return ()) <|> eof
          return (left, opt, right)

准确理解此代码的工作原理并不重要;基本思想是分解您正在解析的内容,在正式规则中表达它,并从较小的组件中重新构建它。对于这样的事情,它会比正则表达式更清晰。


如果你真的想要一个正则表达式,那么你去(几乎没有测试过):

^\s*('[^']*'((\s*\|\s*)'[^'\n]*')*)?(\(~[^)\n]*\))?\s*=\s*('[^']*'((\s*\|\s*)'[^'\n]*')*)?\s*$

了解我推荐解析器的原因?当我第一次写这篇文章的时候,我得到了至少两个错误的东西我拿起来了(每个测试一个),而且可能还有别的东西。而且我没有在你想要的地方插入捕获组,因为我不确定它们会去哪里。现在是的,我可以通过插入评论等使其更具可读性。毕竟,regexen有它们的用途!但问题是:这不是其中之一。坚持用更好的东西。