Javascript 括号、第一个大写字母和数字上的正则表达式拆分

Javascript 括号、第一个大写字母和数字上的正则表达式拆分,javascript,regex,split,Javascript,Regex,Split,现在,我让用户输入一个化学式,比如Cu(NO3)2,然后将元素和数字拆分成一个数组。此代码适用于除带括号的公式外的所有公式。(这实际上来自用户在此处提交的线程。) 我使用replace-then-split的原因是为了确保如果有人输入H12,它将显示为H,12。。。而不是H,1,2 我得到Cu(,N,O,3),2。。。其实我想。。。Cu,(,N,O,3,),2您需要在替换模式中添加括号,如下所示: var userArray=userIn.replace(/\d+|\(|\)/g, '~$&am

现在,我让用户输入一个化学式,比如Cu(NO3)2,然后将元素和数字拆分成一个数组。此代码适用于除带括号的公式外的所有公式。(这实际上来自用户在此处提交的线程。)

我使用replace-then-split的原因是为了确保如果有人输入H12,它将显示为H,12。。。而不是H,1,2


我得到Cu(,N,O,3),2。。。其实我想。。。Cu,(,N,O,3,),2

您需要在替换模式中添加括号,如下所示:

var userArray=userIn.replace(/\d+|\(|\)/g, '~$&').split(/(?=[A-Z])|~/);

使用match代替g标志怎么样:

var userArray=userIn.match(/(?:[A-Z][a-z]*|\d+|[()])/g);

不是正则表达式,更像是可以检查公式的解析器,如果发现错误,则返回指定的数组或
false
。这是非常基本的,但你可以很容易地添加/更改规则(我不是化学家),还包含它检查符号的方法。无论如何,你会发现它很有用

Javascript

var elements = [
    ["89", "Ac", "Actinium", "227"],
    ["13", "Al", "Aluminum", "26.98154"],
    ["56", "Ba", "Barium", "137.33"],
    ["4", "Be", "Beryllium", "9.01218"],
    ["83", "Bi", "Bismuth", "208.9804"],
    ["107", "Bh", "Bohrium", "262"],
    ["48", "Cd", "Cadmium", "112.4"],
    ["20", "Ca", "Calcium", "40.08"],
    ["55", "Cs", "Cesium", "132.9054"],
    ["24", "Cr", "Chromium", "51.996"],
    ["27", "Co", "Cobalt", "58.9332"],
    ["29", "Cu", "Copper", "63.546"],
    ["110", "Ds", "Darmstadtium", "261.9"],
    ["105", "Db", "Dubnium", "261.9"],
    ["87", "Fr", "Francium", "(233)"],
    ["31", "Ga", "Gallium", "69.72"],
    ["79", "Au", "Gold", "196.9655"],
    ["72", "Hf", "Hafnium", "178.49"],
    ["108", "Hs", "Hassium", "264.8"],
    ["49", "In", "Indium", "114.82"],
    ["77", "Ir", "Iridium", "192.2"],
    ["26", "Fe", "Iron", "55.85"],
    ["57", "La", "Lanthanum", "138.91"],
    ["82", "Pb", "Lead", "207.2"],
    ["3", "Li", "Lithium", "6.941"],
    ["12", "Mg", "Magnesium", "24.305"],
    ["25", "Mn", "Manganese", "54.9380"],
    ["109", "Mt", "Meitnerium", "265.9"],
    ["80", "Hg", "Mercury", "200.59"],
    ["42", "Mo", "Molybdenum", "95.94"],
    ["28", "Ni", "Nickel", "58.71"],
    ["41", "Nb", "Niobium", "92.91"],
    ["76", "Os", "Osmium", "190.2"],
    ["46", "Pd", "Palladium", "106.42"],
    ["78", "Pt", "Platinum", "195.09"],
    ["19", "K", "Potassium", "39.0983"],
    ["88", "Ra", "Radium", "226.0254"],
    ["75", "Re", "Rhenium", "186.23"],
    ["45", "Rh", "Rhodium", "102.91"],
    ["37", "Rb", "Rubidium", "85.4678"],
    ["44", "Ru", "Ruthenium", "101.1"],
    ["104", "Rf", "Rutherfordium", "260.9"],
    ["21", "Sc", "Scandium", "44.9559"],
    ["106", "Sg", "Seaborgium", "262.94"],
    ["47", "Ag", "Silver", "107.87"],
    ["11", "Na", "Sodium", "22.98977"],
    ["38", "Sr", "Strontium", "87.62"],
    ["73", "Ta", "Tantalum", "180.95"],
    ["43", "Tc", "Technetium", "(99)"],
    ["81", "Tl", "Thallium", "204.383"],
    ["50", "Sn", "Tin", "118.69"],
    ["22", "Ti", "Titanium", "47.90"],
    ["74", "W", "Tungsten", "183.85"],
    ["112", "Uub", "Ununbium", "276.8"],
    ["116", "Uuh", "Ununhexium", ""],
    ["114", "Uuq", "Ununquadium", "289"],
    ["23", "V", "Vanadium", "50.9414"],
    ["39", "Y", "Yttrium", "88.9059"],
    ["30", "Zn", "Zinc", "65.37"],
    ["40", "Zr", "Zirconium", "91.22"],
    ["51", "Sb", "Antimony", "121.75"],
    ["33", "As", "Arsenic", "74.9216"],
    ["85", "At", "Astatine", "(210)"],
    ["5", "B", "Boron", "10.81"],
    ["32", "Ge", "Germanium", "72.59"],
    ["84", "Po", "Polonium", "(210)"],
    ["14", "Si", "Silicon", "28.0855"],
    ["52", "Te", "Tellurium", "127.6"],
    ["35", "Br", "Bromine", "79.904"],
    ["6", "C", "Carbon", "12.011"],
    ["17", "Cl", "Chlorine", "35.453"],
    ["9", "F", "Fluorine", "18.998403"],
    ["1", "H", "Hydrogen", "1.007825"],
    ["53", "I", "Iodine", "126.9045"],
    ["7", "N", "Nitrogen", "14.0067"],
    ["8", "O", "Oxygen", "15.999"],
    ["15", "P", "Phosphorus", ""],
    ["34", "Se", "Selenium", "78.96"],
    ["16", "S", "Sulphur", "32.06"],
    ["18", "Ar", "Argon", "39.948"],
    ["2", "He", "Helium", "4.00260"],
    ["36", "Kr", "Krypton", "83.80"],
    ["10", "Ne", "Neon", "20.179"],
    ["86", "Rn", "Radon", "(222)"],
    ["54", "Xe", "Xenon", "131.29"],
    ["95", "Am", "Americium", "(243)"],
    ["97", "Bk", "Berkelium", "(247)"],
    ["98", "Cf", "Californium", "(251)"],
    ["58", "Ce", "Cerium", "140.12"],
    ["96", "Cm", "Curium", "(247)"],
    ["66", "Dy", "Dysprosium", "162.50"],
    ["99", "Es", "Einsteinium", "254"],
    ["68", "Er", "Erbium", "167.26"],
    ["63", "Eu", "Europium", "167.26"],
    ["100", "Fm", "Fermium", "(257)"],
    ["64", "Gd", "Gadolinium", "157.25"],
    ["67", "Ho", "Holmium", "164.9"],
    ["103", "Lr", "Lawrencium", "(262)"],
    ["71", "Lu", "Lutetium", "174.97"],
    ["101", "Md", "Mendelevium", "(258)"],
    ["60", "Nd", "Neodymium", ""],
    ["93", "Np", "Neptunium", "(237)"],
    ["102", "No", "Nobelium", "259"],
    ["94", "Pu", "Plutonium", "(244)"],
    ["59", "Pr", "Praseodymium", "140.91"],
    ["61", "Pm", "Promethium", "(147)"],
    ["91", "Pa", "Protactinium", "231.0359"],
    ["62", "Sm", "Samarium", "150.35"],
    ["65", "Tb", "Terbium", "158.92534"],
    ["90", "Th", "Thorium", "232.04"],
    ["69", "Tm", "Thulium", "168.93"],
    ["92", "U", "Uranium", "238.03"],
    ["70", "Yb", "Ytterbium", "173.04"]
];

var symbols = (function (el) {
    var length = el.length,
        i = 0,
        result = [];

    while (i < length) {
        result.push(el[i][2]);
        i += 1;
    }

    return result;
}(elements));

function splitFormula(string) {
    var length = string.length,
        symbolsLength = symbols.length,
        result = [],
        index,
        chars,
        symbol;

    while (string) {
        temp = string.charAt(0).trim();
        if (!temp) {
            string = string.slice(1);
        } else if ("()+-*/".indexOf(temp) !== -1) {
            result.push(temp);
            string = string.slice(1);
        } else if (typeof (+temp) === "number" && isFinite(temp)) {
            temp = parseInt(string).toString();
            result.push(temp);
            string = string.slice(temp.length);
        } else {
            chars = 3;
            while (chars) {
                temp = string.slice(0, chars);
                index = 0;
                while (index < symbolsLength) {
                    if (temp === symbols[index]) {
                        result.push(temp);
                        string = string.slice(chars);
                        break;
                    }

                    index += 1;
                }

                if (index !== symbolsLength) {
                    break;
                }

                chars -= 1;
            }

            if (!chars) {
                return false;
            }
        }
    }

    return result;
}

console.log(splitFormula("Cu(NO3)2 + H2O - H12"));
console.log(splitFormula("Cu(NO3)2 + H2O - X"));


更新:您甚至可以结合括号检查,如中所示。

这是一种比我建议的更好的方法。+1是一个清晰的问题和您尝试过的示例。一个改进可能是包含一个JSFIDLE
var elements = [
    ["89", "Ac", "Actinium", "227"],
    ["13", "Al", "Aluminum", "26.98154"],
    ["56", "Ba", "Barium", "137.33"],
    ["4", "Be", "Beryllium", "9.01218"],
    ["83", "Bi", "Bismuth", "208.9804"],
    ["107", "Bh", "Bohrium", "262"],
    ["48", "Cd", "Cadmium", "112.4"],
    ["20", "Ca", "Calcium", "40.08"],
    ["55", "Cs", "Cesium", "132.9054"],
    ["24", "Cr", "Chromium", "51.996"],
    ["27", "Co", "Cobalt", "58.9332"],
    ["29", "Cu", "Copper", "63.546"],
    ["110", "Ds", "Darmstadtium", "261.9"],
    ["105", "Db", "Dubnium", "261.9"],
    ["87", "Fr", "Francium", "(233)"],
    ["31", "Ga", "Gallium", "69.72"],
    ["79", "Au", "Gold", "196.9655"],
    ["72", "Hf", "Hafnium", "178.49"],
    ["108", "Hs", "Hassium", "264.8"],
    ["49", "In", "Indium", "114.82"],
    ["77", "Ir", "Iridium", "192.2"],
    ["26", "Fe", "Iron", "55.85"],
    ["57", "La", "Lanthanum", "138.91"],
    ["82", "Pb", "Lead", "207.2"],
    ["3", "Li", "Lithium", "6.941"],
    ["12", "Mg", "Magnesium", "24.305"],
    ["25", "Mn", "Manganese", "54.9380"],
    ["109", "Mt", "Meitnerium", "265.9"],
    ["80", "Hg", "Mercury", "200.59"],
    ["42", "Mo", "Molybdenum", "95.94"],
    ["28", "Ni", "Nickel", "58.71"],
    ["41", "Nb", "Niobium", "92.91"],
    ["76", "Os", "Osmium", "190.2"],
    ["46", "Pd", "Palladium", "106.42"],
    ["78", "Pt", "Platinum", "195.09"],
    ["19", "K", "Potassium", "39.0983"],
    ["88", "Ra", "Radium", "226.0254"],
    ["75", "Re", "Rhenium", "186.23"],
    ["45", "Rh", "Rhodium", "102.91"],
    ["37", "Rb", "Rubidium", "85.4678"],
    ["44", "Ru", "Ruthenium", "101.1"],
    ["104", "Rf", "Rutherfordium", "260.9"],
    ["21", "Sc", "Scandium", "44.9559"],
    ["106", "Sg", "Seaborgium", "262.94"],
    ["47", "Ag", "Silver", "107.87"],
    ["11", "Na", "Sodium", "22.98977"],
    ["38", "Sr", "Strontium", "87.62"],
    ["73", "Ta", "Tantalum", "180.95"],
    ["43", "Tc", "Technetium", "(99)"],
    ["81", "Tl", "Thallium", "204.383"],
    ["50", "Sn", "Tin", "118.69"],
    ["22", "Ti", "Titanium", "47.90"],
    ["74", "W", "Tungsten", "183.85"],
    ["112", "Uub", "Ununbium", "276.8"],
    ["116", "Uuh", "Ununhexium", ""],
    ["114", "Uuq", "Ununquadium", "289"],
    ["23", "V", "Vanadium", "50.9414"],
    ["39", "Y", "Yttrium", "88.9059"],
    ["30", "Zn", "Zinc", "65.37"],
    ["40", "Zr", "Zirconium", "91.22"],
    ["51", "Sb", "Antimony", "121.75"],
    ["33", "As", "Arsenic", "74.9216"],
    ["85", "At", "Astatine", "(210)"],
    ["5", "B", "Boron", "10.81"],
    ["32", "Ge", "Germanium", "72.59"],
    ["84", "Po", "Polonium", "(210)"],
    ["14", "Si", "Silicon", "28.0855"],
    ["52", "Te", "Tellurium", "127.6"],
    ["35", "Br", "Bromine", "79.904"],
    ["6", "C", "Carbon", "12.011"],
    ["17", "Cl", "Chlorine", "35.453"],
    ["9", "F", "Fluorine", "18.998403"],
    ["1", "H", "Hydrogen", "1.007825"],
    ["53", "I", "Iodine", "126.9045"],
    ["7", "N", "Nitrogen", "14.0067"],
    ["8", "O", "Oxygen", "15.999"],
    ["15", "P", "Phosphorus", ""],
    ["34", "Se", "Selenium", "78.96"],
    ["16", "S", "Sulphur", "32.06"],
    ["18", "Ar", "Argon", "39.948"],
    ["2", "He", "Helium", "4.00260"],
    ["36", "Kr", "Krypton", "83.80"],
    ["10", "Ne", "Neon", "20.179"],
    ["86", "Rn", "Radon", "(222)"],
    ["54", "Xe", "Xenon", "131.29"],
    ["95", "Am", "Americium", "(243)"],
    ["97", "Bk", "Berkelium", "(247)"],
    ["98", "Cf", "Californium", "(251)"],
    ["58", "Ce", "Cerium", "140.12"],
    ["96", "Cm", "Curium", "(247)"],
    ["66", "Dy", "Dysprosium", "162.50"],
    ["99", "Es", "Einsteinium", "254"],
    ["68", "Er", "Erbium", "167.26"],
    ["63", "Eu", "Europium", "167.26"],
    ["100", "Fm", "Fermium", "(257)"],
    ["64", "Gd", "Gadolinium", "157.25"],
    ["67", "Ho", "Holmium", "164.9"],
    ["103", "Lr", "Lawrencium", "(262)"],
    ["71", "Lu", "Lutetium", "174.97"],
    ["101", "Md", "Mendelevium", "(258)"],
    ["60", "Nd", "Neodymium", ""],
    ["93", "Np", "Neptunium", "(237)"],
    ["102", "No", "Nobelium", "259"],
    ["94", "Pu", "Plutonium", "(244)"],
    ["59", "Pr", "Praseodymium", "140.91"],
    ["61", "Pm", "Promethium", "(147)"],
    ["91", "Pa", "Protactinium", "231.0359"],
    ["62", "Sm", "Samarium", "150.35"],
    ["65", "Tb", "Terbium", "158.92534"],
    ["90", "Th", "Thorium", "232.04"],
    ["69", "Tm", "Thulium", "168.93"],
    ["92", "U", "Uranium", "238.03"],
    ["70", "Yb", "Ytterbium", "173.04"]
];

var symbols = (function (el) {
    var length = el.length,
        i = 0,
        result = [];

    while (i < length) {
        result.push(el[i][2]);
        i += 1;
    }

    return result;
}(elements));

function splitFormula(string) {
    var length = string.length,
        symbolsLength = symbols.length,
        result = [],
        index,
        chars,
        symbol;

    while (string) {
        temp = string.charAt(0).trim();
        if (!temp) {
            string = string.slice(1);
        } else if ("()+-*/".indexOf(temp) !== -1) {
            result.push(temp);
            string = string.slice(1);
        } else if (typeof (+temp) === "number" && isFinite(temp)) {
            temp = parseInt(string).toString();
            result.push(temp);
            string = string.slice(temp.length);
        } else {
            chars = 3;
            while (chars) {
                temp = string.slice(0, chars);
                index = 0;
                while (index < symbolsLength) {
                    if (temp === symbols[index]) {
                        result.push(temp);
                        string = string.slice(chars);
                        break;
                    }

                    index += 1;
                }

                if (index !== symbolsLength) {
                    break;
                }

                chars -= 1;
            }

            if (!chars) {
                return false;
            }
        }
    }

    return result;
}

console.log(splitFormula("Cu(NO3)2 + H2O - H12"));
console.log(splitFormula("Cu(NO3)2 + H2O - X"));
["Cu", "(", "N", "O", "3", ")", "2", "+", "H", "2", "O", "-", "H", "12"] 
false