RegEx用于解析化学式

时间:2014-05-12 06:14:26

标签: regex

我需要一种方法将化学式分离成其组分。结果应该是这样的 这样:

   Ag3PO4 -> [Ag3, P, O4]
      H2O -> [H2, O]
   CH3OOH -> [C, H3, O, O, H]
Ca3(PO4)2 -> [Ca3, (PO4)2]

我不知道正则表达式语法,但我知道我需要这样的东西

[可选括号] [大写字母] [0或更多小写字母] [0或更多数字] [可选括号] [0或更多数字]

这有效

NSRegularExpression *regex = [NSRegularExpression
                              regularExpressionWithPattern:@"[A-Z][a-z]*\\d*|\\([^)]+\\)\\d*"
                              options:0
                              error:nil];
NSArray *tests = [[NSArray alloc ] initWithObjects:@"Ca3(PO4)2", @"HCl", @"CaCO3", @"ZnCl2", @"C7H6O2", @"BaSO4", nil];
for (NSString *testString in tests)
{
    NSLog(@"Testing: %@", testString);
    NSArray *myArray = [regex matchesInString:testString options:0 range:NSMakeRange(0, [testString length])] ;
    NSMutableArray *matches = [NSMutableArray arrayWithCapacity:[myArray count]];

    for (NSTextCheckingResult *match in myArray) {
        NSRange matchRange = [match rangeAtIndex:0];
        [matches addObject:[testString substringWithRange:matchRange]];
        NSLog(@"%@", [matches lastObject]);
    }
}

4 个答案:

答案 0 :(得分:14)

(PO4)2真的与众不同。

让我们从简单的匹配项开始,不带括号:

[A-Z][a-z]?\d*

使用上面的正则表达式,我们可以成功解析Ag3PO4H2OCH3OOH

然后我们需要以某种方式为组添加表达式。可以使用以下方式匹配组:

\(.*?\)\d+

所以我们添加or条件:

[A-Z][a-z]?\d*|\(.*?\)\d+

Regular expression visualization

Demo

适用于特定情况。但也许你会有更多的样本。

注意:嵌套式括号会出现问题。防爆。 Co3(Fe(CN)6)2

如果要处理该情况,可以使用以下正则表达式:

[A-Z][a-z]?\d*|(?<!\([^)]*)\(.*\)\d+(?![^(]*\))

Regular expression visualization

对于Objective-C,您可以使用不带外观的表达式:

[A-Z][a-z]?\d*|\([^()]*(?:\(.*\))?[^()]*\)\d+

Regular expression visualization

Demo

或重复的正则表达式(我不知道这样的公式,但如果有A(B(CD)3E(FG)4)5之类的东西 - 一个内有多个括号块。

[A-Z][a-z]?\d*|\((?:[^()]*(?:\(.*\))?[^()]*)+\)\d+

Regular expression visualization

Demo

答案 1 :(得分:3)

这应该只是工作:

/(\(?)([A-Z])([a-z]*)([0-9]*)(\))?([0-9]*)/g

在此处使用它:http://refiddle.com/

答案 2 :(得分:3)

当你遇到括号组时,你不想解析里面的内容,对吗?

如果没有嵌套的括号组,您只需使用

即可
[A-Z][a-z]*\d*|\([^)]+\)\d*

\d[0-9]的缩写,[^)]表示除括号外的任何内容。

请参阅demo here

答案 3 :(得分:2)

此模式应根据您的RegEx引擎工作 具有([A-Z][a-z]*\d*)|(\((?:[^()]+|(?R))*\)\d*)选项的gm Demo