我正在尝试解析包含参数属性的文件。属性设置如下:
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的值中提取名称。我的想法是,如果我可以根据参数声明中的空格创建一个正则表达式匹配,那么我可以在将该行提供给拆分器/解析器之前删除这些空格。然而,我正在艰难地想出适当的正则表达式。是否可以创建仅匹配参数声明中的空格的正则表达式,但忽略参数声明之间的空格?
答案 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 ,然后是字符(属性名称)和=
。如果找到这个,它将停止匹配。负前瞻检查空格的事实意味着它将停止在公式末尾没有尾随空格。
答案 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
});
结果: