ak85
ak85

Reputation: 4264

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?

Upvotes: 1

Views: 3016

Answers (5)

Anonymous0day
Anonymous0day

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

Victor
Victor

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);

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>

Upvotes: 0

Vidul
Vidul

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

Samphors
Samphors

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

hwnd
hwnd

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

Related Questions