简体   繁体   中英

How to remove the last matched regex pattern in javascript

I have a text which goes like this...

var string = '~a=123~b=234~c=345~b=456'

I need to extract the string such that it splits into

['~a=123~b=234~c=345','']

That is, I need to split the string with /b=.*/ pattern but it should match the last found pattern. How to achieve this using RegEx?

The numbers present after the equal is randomly generated. 等号后的数字是随机生成的。

The above one was just an example. I did not make the question clear I guess. Generalized String being...

<word1>=<random_alphanumeric_word>~<word2>=<random_alphanumeric_word>..~..~..<word2>=<random_alphanumeric_word>

All have random length and all word i are alphabets, the whole string length is not fixed. the only text known would be <word2> . Hence I needed RegEx for it and pattern being /<word2>=.*/

This doesn't sound like a job for regexen considering that you want to extract a specific piece. Instead, you can just use lastIndexOf to split the string in two:

var lio = str.lastIndexOf('b=');

var arr = [];
var arr[0] = str.substr(0, lio);
var arr[1] = str.substr(lio);

http://jsfiddle.net/NJn6j/

A RegExp that will give a result that you may could use is:

string.match(/[a-z]*?=(.*?((?=~)|$))/gi);
// ["a=123", "b=234", "c=345", "b=456"]

But in your case the simplest solution is to split the string before extract the content:

var results = string.split('~'); // ["", "a=123", "b=234", "c=345", "b=456"]

Now will be easy to extract the key and result to add to an object:

var myObj = {};
results.forEach(function (item) { 
    if(item) { 
        var r = item.split('='); 
        if (!myObj[r[0]]) {
            myObj[r[0]] = [r[1]]; 
        } else {
            myObj[r[0]].push(r[1]); 
        }
    } 
});
console.log(myObj);

Object:

  • a: ["123"]
  • b: ["234", "456"]
  • c: ["345"]

Assuming the format is ( ~ , alphanumeric name, = , and numbers) repeated arbitrary number of times. The most important assumption here is that ~ appear once for each name-value pair, and it doesn't appear in the name.

You can remove the last token by a simple replacement:

str.replace(/(.*)~.*/, '$1')

This works by using the greedy property of * to force it to match the last ~ in the input.

This can also be achieved with lastIndexOf , since you only need to know the index of the last ~ :

str.substring(0, (str.lastIndexOf('~') + 1 || str.length() + 1) - 1)

(Well, I don't know if the code above is good JS or not... I would rather write in a few lines. The above is just for showing one-liner solution).

I don't think I'd personally use a regex for this type of problem, but you can extract the last option pair with a regex like this:

var str = '~a=123~b=234~c=345~b=456';
var matches = str.match(/^(.*)~([^=]+=[^=]+)$/);

// matches[1] = "~a=123~b=234~c=345"
// matches[2] = "b=456"

Demo: http://jsfiddle.net/jfriend00/SGMRC/

(?=.*(~b=[^~]*))\1 

will get it done in one match, but if there are duplicate entries it will go to the first. Performance also isn't great and if you string.replace it will destroy all duplicates. It would pass your example, but against '~a=123~b=234~c=345~b=234' it would go to the first 'b=234'.

.*(~b=[^~]*) 

will run a lot faster, but it requires another step because the match comes out in a group:

var re = /.*(~b=[^~]*)/.exec(string);
var result = re[1]; //~b=234
var array = string.split(re[1]);

This method will also have the with exact duplicates. Another option is:

var regex = /.*(~b=[^~]*)/g;
var re = regex.exec(string);
var result = re[1];
// if you want an array from either side of the string:
var array = [string.slice(0, regex.lastIndex - re[1].length - 1), string.slice(regex.lastIndex, string.length)];

This actually finds the exact location of the last match and removes it regex.lastIndex - re[1].length - 1 is my guess for the index to remove the ellipsis from the leading side, but I didn't test it so it might be off by 1.

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