简体   繁体   中英

regex remove everything after character including that charecter

I want to complete a regex which matches everything after a certain character including that character. eg if my string is

"12:23:34:45:56"

I want to return

"12:23:34:45"

Where everything after the last : has been removed including the :

I tried the below.

 var str1 = "12:23:34:45:56"; str1 = str1.replace(/[^:]*$/,""); alert(str1); 

Which returns "12:23:34:45:" (need to get rid of the last :)

I also tried

 var str2 = "12:23:34:45:56"; str2 = str2.replace(/:.*$/,""); alert(str2); 

which returns "12" matches to much of the string

How can I get what I want here?

Regexpless solution:

var r = '12:23:34:45:56'.split(':').slice(0,-1).join(':');
console.log(r); //=> "12:23:34:45"

Another options are positive lookahead :

var result = '12:23:34:45:56'.match(/(.+)(?=:).+/, '$1')[1];

or, as already noted by Matt Way , lastIndexOf :

var result = '12:23:34:45:56'.slice(0, '12:23:34:45:56'.lastIndexOf(':'));

Update: lastIndexOf & slice looks like the best solution in terms of performance .

Maybe you should consider this simple solution :

var str='12:23:34:45:56';
var len = str.length;
while(len && str[len]!==':')len--;
var result = str.substr(0,len) 
console.log(result); // will output=> 12:23:34:45

Test :

 var i=0; var tryIt=function(){ var inputStr=document.getElementById('input').value; var len = inputStr.length; while(len && inputStr[len]!==':')len--; var str = inputStr.substr(0,len) console.log(str); // will output=> 12:23:34:45 document.getElementById('output').innerHTML = 'result N°'+ (i++) + ' : <span>' + str + '</span>'; } document.getElementById('tryButton').onclick = tryIt; 
 input { padding : 6px; margin : 3px; font-size : 1em; } div { margin : 6px; } span { border : solid 1px #999; border-radius : 9px ; padding : 6px; } 
 <div><input type='text' id='input' value='12:23:34:45:56' ></div> <div id='output'></div> <hr><button id='tryButton'>try it</button> 

Benchmarking :

 var inputStr = '12:23:34:45:56'; var len = inputStr.length ; var suite = new Benchmark.Suite('foo', { 'onStart': function(event) { console.log(this, event); out("Benchmark running... (please don't scroll)"); }, 'onCycle': function(event) { console.log(this, event); out(String(event.target)); }, 'onComplete': function(event) { console.log(this, event); out('Benchmark ended.'); out('Fastest is "' + this.filter('fastest').pluck('name')+'"'); } }); suite.add("String split.slice.join", function() { var str = inputStr.split(':').slice(0, -1).join(':'); }); suite.add("Positive lookahead:", function() { var str = inputStr.match(/(.+)(?=:).+/, '$1')[1]; }); suite.add("Regex replace", function() { var str = inputStr.replace(/(.+):.+/, "$1"); }); suite.add("While loop", function() { len = inputStr.length; while(len && inputStr[len]!==':')len--; var str = inputStr.substring(0,len) }); suite.add("Slice lastIndeOf", function() { var str = inputStr.slice(0, inputStr.lastIndexOf(':')); }); suite.add("While loop, with outside len", function() { while(len && inputStr[len]!==':')len--; var str = inputStr.substring(0,len) }); suite.run({ 'async': true }); function out(str) { output.innerHTML += str + "\\n"; } 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/benchmark/1.0.0/benchmark.js"></script> <pre id="output"></pre> 

Edit : Modified Benchmark test

the best choice is to use @CPH4 solution (noted by Matt Way) : Slice.lastIndexOf .

But if your texts input have all the same length so you have to consider the negative while loop .

For me I don't know my answer matches with your need or not but I just want to help.

Instead of using replace() function you can use split() function to solve with that problem:

example :

var mystr = '12:23:34:45:56';
var myarr = mystr.split(":");
var myvar = myarr[0] + ":" + myarr[1] + ":" + myarr[2] + ":" + myarr[3];

alert(myvar);

or you can use this to remove : in the last

var mystr = '12:23:34:45:56';
var myarr = mystr.split(":");
myarr.pop();
var myvar = myarr.join(":");

alert(myvar);

Let's try it.

Encapsulate the part you need in a capturing group, then you can use $n to get it.

Using a gredy match against "12:23:34:45:56"

/(.*)(:.*)/

Then used the first capture group $1 is going to be "12:23:34:45" and $2 ":45"

 var str = "12:23:34:45:56".replace(/(.+):.+/,"$1"); document.write(str); 

Benchmark

String split.slice.join x 946,879 ops/sec ±0.53% (66 runs sampled)
Regex replace x 2,685,153 ops/sec ±0.87% (67 runs sampled)
Benchmark ended. Fastest is "Regex replace"

 var suite = new Benchmark.Suite('foo', { 'onStart': function(event) { console.log(this, event); out("Benchmark running... (please don't scroll)"); }, 'onCycle': function(event) { console.log(this, event); out(String(event.target)); }, 'onComplete': function(event) { console.log(this, event); out('Benchmark ended.'); out('Fastest is "' + this.filter('fastest').pluck('name')+'"'); } }); suite.add("String split.slice.join", function() { var str = '12:23:34:45:56'.split(':').slice(0, -1).join(':'); }); suite.add("Regex replace", function() { var str = "12:23:34:45:56".replace(/(.+):.+/, "$1"); }); suite.run({ 'async': true }); function out(str) { output.innerHTML += str + "\\n"; } 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/benchmark/1.0.0/benchmark.js"></script> <pre id="output"></pre> 

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