Reputation: 4264
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?
Upvotes: 1
Views: 3016
Reputation: 3042
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
.
Upvotes: 1
Reputation: 22208
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);
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>
Upvotes: 0
Reputation: 10556
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.
Upvotes: 2
Reputation: 530
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.
Upvotes: 0
Reputation: 70750
Regexpless solution:
var r = '12:23:34:45:56'.split(':').slice(0,-1).join(':');
console.log(r); //=> "12:23:34:45"
Upvotes: 5