我需要一种方法来将化学式分解成各个组成部分。结果应该是这样的 这个:
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*
使用上面的正则表达式我们可以成功解析Ag3PO4
、H2O
、CH3OOH
。
然后我们需要以某种方式为组添加表达式。 Group by 自身可以使用以下方式进行匹配:
\(.*?\)\d+
所以我们添加或
条件:
[A-Z][a-z]?\d*|\(.*?\)\d+
这适用于给定的情况。但也许您有更多 sample 。
注意:嵌套括号会有问题。前任。 Co3(Fe(CN)6)2
如果你想处理这种情况,你可以使用下面的正则表达式:
[A-Z][a-z]?\d*|(?<!\([^)]*)\(.*\)\d+(?![^(]*\))
对于 Objective-C,您可以使用没有环顾四周的表达式:
[A-Z][a-z]?\d*|\([^()]*(?:\(.*\))?[^()]*\)\d+
或带有重复的正则表达式(我不知道这样的公式,但如果有类似 A(B(CD)3E(FG)4)5
的情况 - 一个内有多个括号 block .
[A-Z][a-z]?\d*|\((?:[^()]*(?:\(.*\))?[^()]*)+\)\d+
关于objective-c - 用于解析化学式的 RegEx,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23602175/