正则表达式抓住公式

时间:2016-03-31 15:07:18

标签: regex perl

我正在尝试解析包含参数属性的文件。属性设置如下:

w=(nf*40e-9)*ng

但也喜欢这样:

par_nf=(1) * (ng)

问题是,所有这些参数定义都在源文件中的一行上,并且它们用空格分隔。所以你可能会遇到这样的情况:

pd=2.0*(84e-9+(1.0*nf)*40e-9) nf=ng m=1 par=(1) par_nf=(1) * (ng) plorient=0

当前算法只是在空格上划分行,然后对于每个标记,从=的LHS和RHS的值中提取名称。我的想法是,如果我可以根据参数声明中的空格创建一个正则表达式匹配,那么我可以在将该行提供给拆分器/解析器之前删除这些空格。然而,我正在艰难地想出适当的正则表达式。是否可以创建仅匹配参数声明中的空格的正则表达式,但忽略参数声明之间的空格

3 个答案:

答案 0 :(得分:1)

试试这个RegEx:

(?<=^|\s)       # Start of each formula (start of line OR [space])
(?:.*?)         # Attribute Name
=               # =
(?:             # Formula
(?!\s\w+=)        # DO NOT Match [space] Word Characters = (Attr. Name)
[^=]              # Any Character except =
)*              # Formula Characters repeated any number of times

检查公式字符时,它使用负前瞻来检查 Space ,然后是字符(属性名称)和=。如果找到这个,它将停止匹配。负前瞻检查空格的事实意味着它将停止在公式末尾没有尾随空格。

Live Demo on Regex101

答案 1 :(得分:0)

感谢@Andy的提示:

在这种情况下,我可能只是匹配参数名称和equals,但将前面的空格替换为其他“可解析”字符以便拆分,如下所示:

(\s*)\w+[a-zA-Z_]=

现在我的第一个捕获组可用于插入冒号,分号或换行符等内容。

答案 2 :(得分:0)

您需要添加Perl标记。 :-(也许这会有所帮助:

我最终在C#中使用它。我们的想法是将其分解为名称值对,使用指定为关键的负向前瞻来停止匹配并开始新的匹配。如果这有帮助

var data = @"pd=2.0*(84e-9+(1.0*nf)*40e-9) nf=ng m=1 par=(1) par_nf=(1) * (ng) plorient=0";

var pattern = @"
(?<Key>[a-zA-Z_\s\d]+)           # Key is any alpha, digit and _
=                                # = is a hard anchor
(?<Value>[.*+\-\\\/()\w\s]+)     # Value is any combinations of text with space(s)
(\s|$)                           # Soft anchor of either a \s or EOB
((?!\s[a-zA-Z_\d\s]+\=)|$)       # Negative lookahead to stop matching if a space then key then equal found or EOB
";

Regex.Matches(data, pattern, RegexOptions.IgnorePatternWhitespace | RegexOptions.ExplicitCapture)
     .OfType<Match>()
     .Select(mt => new
     {
         LHS = mt.Groups["Key"].Value,
         RHS = mt.Groups["Value"].Value
     });

结果:

enter image description here