简体   繁体   中英

How do I extract the coefficients and variables of an algebraic expression in an array using regex in javascript?

I want to store the algebraic parts in an array. Currently, I have this but it's not fully working.

function exp(term) {
    var container = [];
    if (term[0] === '-') {
        container[0] = '-1';
        container[1] = term.match(/([0-9]+)/g)[0];
        container[2] = term.match(/([a-zA-Z]+)/g)[0];
    } 
    else {
        container[0] = '0';
        container[1] = term.match(/([0-9]+)/g)[0];
        container[2] = term.match(/([a-zA-Z]+)/g)[0];
    }
    return container;
}

console.log(exp('-24mn'));    //should output ['-1', '24', 'mn']
console.log(exp('-100BC'));   //should output ['-1', '100', 'BC']
console.log(exp('100BC'));    //should output ['0', '100', 'BC']
console.log(exp('100'));      //should output ['0', '100', '']
console.log(exp('BC'));       //should output ['0', '0', 'BC']
console.log(exp('-bC'));      //should output ['-1', '0', 'bC']
console.log(exp('-100'));     //should output ['-1', '100', '']

But if possible, what I really want is an array of length 2 only, containing the coefficient and the variables like:

console.log(exp('-24mn'));    //should output ['-24', 'mn']
console.log(exp('-100BC'));   //should output ['-100', 'BC']
console.log(exp('100BC'));    //should output ['100', 'BC']
console.log(exp('100'));      //should output ['100', '']
console.log(exp('BC'));       //should output ['0', 'BC']
console.log(exp('-bC'));      //should output ['-1', 'bC']
console.log(exp('-100'));     //should output ['-100', '']

I only did the array of length 3 approach because I don't know how to deal with a case where there's only a negative sign followed by variables like '-bC' and also only variables like 'BC'. Any help will be greatly appreciated. Thanks in advance!

Your can use groups to capture the two parts and add some additional logic for handling cases where the number is not present in the input:

function exp(term) {
    const matches = term.match(/(-?[0-9]*)([a-zA-Z]*)/);
    return [convertNumMatch(matches[1]), matches[2]];
}

function convertNumMatch(numMatch) {
    if (!numMatch)
        return '0';
    else if (numMatch === '-')
        return '-1';
    else
        return numMatch;
}

The pattern that you tried, contains all optional parts which could also match an empty string.

You could use an alternation with 4 capture groups. Then return an array with either group 1 and 2, or an array with group 3 and 4.

The value of 0 and -1 can be determined by checking if group 3 (denoted as m[3] in the code) exists.

^(-?\d+)([a-z]*)|(-)?([a-z]+)$
  • ^ Start of string
  • (-?\d+) Capture group 1 Match optional - and 1+ digits
  • ([az]*) Capture group 2 Capture optional chars a-zA-Z
  • | Or
  • (-)? Optional capture group 3 Match -
  • ([az]+) Capture group 4 Match 1+ chars a-zA-Z
  • $ End of string

Regex demo

Example using a case insensitive match using the /i flag:

 const regex = /^(-?\d+)([az]*)|(-)?([az]+)$/gi; const exp = str => Array.from( str.matchAll(regex), m => m[4]? [m[3]? -1: 0, m[4]]: [m[1], m[2]] ); [ "-24mn", "-100BC", "100BC", "100", "BC", "-bC", "-100", "" ].forEach(s => console.log(exp(s)) );

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM