解析化学式的RegEx

sirbozc5  于 2023-05-08  发布在  其他
关注(0)|答案(5)|浏览(228)

我需要一种方法把一个化学式分解成它的组成部分。结果应该如下所示:

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

我不知道正则表达式语法,但我知道我需要这样的东西
[An可选括号][大写字母][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]);
    }
}
vjrehmav

vjrehmav1#

(PO4)2真的坐在旁边的所有。
让我们从简单的开始,匹配没有括号的项目:

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

使用上面的正则表达式,我们可以成功解析Ag3PO4H2OCH3OOH
然后,我们需要以某种方式为组添加表达式。Group by本身可以使用以下命令进行匹配:

\(.*?\)\d+

所以我们添加or条件:

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

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

**注意:**嵌套括号会有问题。例如Co3(Fe(CN)6)2

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

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

对于Objective-C,你可以不用查找就使用这个表达式:

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

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

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

Demo

axkjgtzd

axkjgtzd2#

当你遇到一个括号组时,你不想解析里面的内容,对吧?
如果没有嵌套的括号组,则可以简单地使用

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

\d[0-9]的简写,[^)]表示除括号以外的任何含义。
参见demo here

nbewdwxp

nbewdwxp3#

这应该只是关于工作:

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

polhcujo4#

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

d6kp6zgx

d6kp6zgx5#

最好将字符集限制为有效的化学名称。以简单的形式:
^((Ac|银|艾尔|上午|阿|作为|在|Au| B|巴|Be| Bh|毕|Bk| Br| C类|Ca|镉|切|Cf|氯|厘米|Co| chrome |CS|铜|Ds| Db|镝|额|Es|欧盟|F级|铁元素|Fm|弗瑞德|加|Gd|格|H|何|高频|汞|何|HS|我的|输入|Ir| K| Kr|拉|李|Lr|吕|MD|镁|锰|莫|山|N|纳|铌|钕|讷|镍|不想|NP| O型|奥斯|P|啪|铅|钯|PM|波|Pr| Pt|普|拉|Rb| Re|射频|RG| Rh| Rn|汝|S|锑|Sc| selenium |SG|四|Sm| Sn|锶|Ta| Tb| Tc|特|日|钛|Tl| Tm| U| V| W| Xe| Y|镱|锌|Zr)\d*)+$
这并不处理带括号的组。
这是我们在圣地亚哥Python用户组会议上解决的。

相关问题