简体   繁体   中英

Extract all groups after character with regex

The goal is to extract all the pairs key/value from a string which has the following format:

(&(foo=bar)(goo=car)) or (|(foo=bar)(goo=car)(hoo=dar))

I don't know how much groups are there, could be 2, could be 50.

I need to extract the operator ( & or | ) and the single params.

I tried the following regex, but it ignores the first group:

([|&])((\(.*?=.*?\)))+

How can I get all the groups?

my attempt

EDIT

I think I might got it working by applying 2 regexps

\(([|&])(.*)\)

this will extract only the content

(foo=bar)(goo=car)

and this would extract the content

\((.*?)\)

foo=bar, goo=car

 let match = null; const regex = /(\([^&|]+?=.+?)\)/g; while (match = regex.exec('(&(foo=bar)(goo=car))')) { console.log(match[0]); }

I managed to do everything as expected


@Injectable()
export class QueryService {

regex1: RegExp = new RegExp("^\\(([|&])(.*)\\)");
regex2: RegExp = new RegExp("\\(([&|]\\(.*\\)\\(.*?\\)).*?\\)|\\(.*?\\)", "g");
regex3: RegExp = new RegExp("\\((.*?)\\)");

constructor(){}

decode(query: string): Query {
    if (!this.regex1.test(query)) {
      console.error("Error while parsing query", query);
      return;
    }
    const matches = query.match(this.regex1);
    const parts = {
      operator: matches[1] as QueryConditions,
      content: matches[2].match(this.regex2)
    };

    return new Query(parts.operator, this._getQueryFields(parts.content));
}

private _getQueryFields(content: string[]): GenericObject {
    const mapped: GenericObject = {};
    forEach(content, (g) => {
      if (this.regex1.test(g)) {
        mapped.group = this.decode(g);
      }
      else {
        //
        const pair = g.match(this.regex3)[1].split("=");
        mapped[pair[0]] = pair[1];
      }
    });

    return mapped;
  }

}

Somewhere in my app

source: string = new Query("&", {
    foo: "bar",
    goo: "car",
    group: new Query("&", {
      firstName: "john",
      lastName: "doe"
    })
}).generate();

decoded: Query = this._queryService.decode(source);

// source = (&(foo=bar)(goo=car)(&(firstName=john)(lastName=doe)))

// decode will produce a map 
/* {
     operator: "&",
     fields: {
        foo: "bar",
        goo: "car",
        group: {
           operator: "&",
           fields: {
               firstName: "john",
               lastName: "doe"
           }
       }
   } */

of course I can handle multiple groups at the same level, but for now this is enough. I'll improve the code gradually.

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