objective-c - 用于解析化学式的 RegEx

标签 objective-c 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]);
    }
}

最佳答案

(PO4)2 确实与众不同。

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

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

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

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

\(.*?\)\d+

所以我们添加条件:

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

Regular expression visualization

Demo

这适用于给定的情况。但也许您有更多 sample 。

注意:嵌套括号会有问题。前任。 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 的情况 - 一个内有多个括号 block .

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

Regular expression visualization

Demo

关于objective-c - 用于解析化学式的 RegEx,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23602175/

相关文章:

objective-c - Game Center 不响应 authenticateWithCompletionHandler 请求 (iOS)

javascript - 从扑克之星历史中解析席位

java - String.split() 没有按预期工作

javascript正则表达式不包含中间的单词

iphone - 响应UIWebView点击 Action 调用原生代码页

objective-c - if语句: I found something strange. 为什么我的第二个 'if'等于no?

ios - 在后台连续运行的iOS游戏

objective-c - NSDateFormatter 返回 nil

regex - 如何在 Azure API 管理策略表达式中添加正则表达式验证

c++ - 向此正则表达式添加最少字符