How can I add a dot between two numbers? - javascript

I'm trying to add a dot between two numbers. It's about article numbers, for now they were like XXXXX or XXXXXX and now should be XXX.XX or XXX.XXX which I can't figure out.
Article numbers are loaded automatically from database since there are a lot of them. Right now, they are 99-87503 or 99-400031, and from now on should be 99.875.03 or 99.400.031.
I've tried with specifying numbers, filters and patterns none of which worked.
Current AngularJs code:
<div class="status">
99.{{Manipulated()}} |
<p ng-model="Manipulated"
class="rwd-info-msg {{Manipulated.cssClass}}">
{{Manipulated.text}}
</p>
</div>
This 99. is just a prefix that should be at every article number.
I'm pretty new to AngularJS, so any help would be appreciated.

The naive thing you could do is
var num = 9876543;
var res = num.toString().replace(/^(\d{3})(.*)/ig, '$1.$2');
console.log(num, '->', res);
Here, the (\d{3}) part captures the first 3 digits while the (.*) captures the rest.
You can then access each part with $1 to get the first captured group and $2 to get the second captured group.
I'm certain that there are way better solutions, but that a starting point.

This expression,
(?<=^[0-9]{3})
with a replacement of . might also work.
const regex = /(?<=^[0-9]{3})/g;
const str = `9876544`;
const subst = `.`;
const result = str.replace(regex, subst);
console.log(result);
The expression is explained on the top right panel of regex101.com, if you wish to explore/simplify/modify it, and in this link, you can watch how it would match against some sample inputs, if you like.

AngularJS way of doing this is creating a custom filter:
app.filter('addDot', function() {
return function(number) {
return number.toString().slice(0,3) + number.toString().slice(3);
};
})
and use it in your template like:
<div class="article-status">
99.{{getManipulatedArticle(article).artnr | addDot}} </p>
</div>

Related

How to capture one particular instance of a string only if it occurs twice in regex?

I have a regex expression:
/diff\\left\((...*?\\right\){0,1})\\right\)/gm
and the string I want to match is
diff\left(5x^2\right) + diff\left(5x^2+\tan\left(x\right)\right)
I want to match in such a way that there are two matches:diff\left(5x^2+\right) and diff\left(5x^2+\tan\left(x\right)\right)
each having captured groups 5x^2 and 5x^2+\tan\left(x\right).
I want to add \right) inside a captured group once only if it occurs twice.
However, I'm only getting a single match with the entire 5x^2\right)+diff\left(5x^2+\tan\left(x\right) inside a captured group.
Here are two images for better understanding. Blue parts represent matches and green parts represent captured groups
Here is the output I'm getting (screenshot from regex101)
Desired output (this is an edited image)
Please help me with this I'm trying to build a symbolic calculator app. Thanks
If those two parts are to always be bound by space characters, you could try something like the below:
https://regex101.com/r/Lcsxxv/1
const regex = /diff\\left\(([^ ]*)\\right\)/gm;
const str = `diff\\left(5x^2\\right) + diff\\left(5x^2+\\tan\\left(x\\right)\\right)`;
const matches = [];
const groups = [];
let r;
while ((r = regex.exec(str)) !== null) {
matches.push(r[0]);
groups.push(r[1]);
}
console.log(`matches:\n\t${matches.join('\n\t')}
groups:\n\t${groups.join('\n\t')}`)
The way it works is that it's going to look for the last instance of \right) until either the end of the string or a space character, whichever comes first.
I hope this answers your question.

Multiple quotes in comments with replace

I need to transform this:
[quote=mvneobux]My first comment[/quote]
I liked your comment.
In that:
<div class="quote">
<div class="author">mvneobux:</div>
My first comment.
</div>
I liked your comment.
the solution date in another topic works perfectly when there is only one quote. but two quotes or more don't work.
The current code is as follows
comment.replace(/\[quote=(.+?)\](.+?)\[\/quote\]/, '<div class="quote"><div class="author"> $1 </div> $2 </div>');
but in the following scenario the result is broken:
[quote=username2][quote=mvneobux]interessante e bom continue[/quote][/quote]
How can I solve? remembering that there may be several quotes within each other. How could I take each one separately?
Instead of using .*? to match the content in the middle, match anything but [quote=SOMETHING] with ((?:(?!\[quote).)*?). Then, replace one at a time, until there are no more matches:
let str = `[quote=mvneobux][quote=charlote]parabens pelo relato[/quote] legal seu relato[/quote]interessante`;
const pattern = /\[quote=([^\]]+)\]((?:(?!\[quote).)*?)\[\/quote\]/;
while (pattern.test(str)) {
str = str.replace(pattern, '<div class="quote"><div class="author">$1</div>$2</div>');
}
console.log(str);
Another options is just creating a simpler RegEx expression and use a simple replace in combination like
let result = `[quote=mvneobux]My first comment[/quote]
I liked your comment.`
.replace(/\[quote=(.+?)\]/,"<div class='author'>$1<div>")
.replace("[/quote]", "<div>");
console.log(result);

regex to remove certain characters at the beginning and end of a string

Let's say I have a string like this:
...hello world.bye
But I want to remove the first three dots and replace .bye with !
So the output should be
hello world!
it should only match if both conditions apply (... at the beginning and .bye at the end)
And I'm trying to use js replace method. Could you please help? Thanks
First match the dots, capture and lazy-repeat any character until you get to .bye, and match the .bye. Then, you can replace with the first captured group, plus an exclamation mark:
const str = '...hello world.bye';
console.log(str.replace(/\.\.\.(.*)\.bye/, '$1!'));
The lazy-repeat is there to ensure you don't match too much, for example:
const str = `...hello world.bye
...Hello again! Goodbye.`;
console.log(str.replace(/\.\.\.(.*)\.bye/g, '$1!'));
You don't actually need a regex to do this. Although it's a bit inelegant, the following should work fine (obviously the function can be called whatever makes sense in the context of your application):
function manipulate(string) {
if (string.slice(0, 3) == "..." && string.slice(-4) == ".bye") {
return string.slice(4, -4) + "!";
}
return string;
}
(Apologies if I made any stupid errors with indexing there, but the basic idea should be obvious.)
This, to me at least, has the advantage of being easier to reason about than a regex. Of course if you need to deal with more complicated cases you may reach the point where a regex is best - but I personally wouldn't bother for a simple use-case like the one mentioned in the OP.
Your regex would be
const rx = /\.\.\.([\s\S]*?)\.bye/g
const out = '\n\nfoobar...hello world.bye\nfoobar...ok.bye\n...line\nbreak.bye\n'.replace(rx, `$1!`)
console.log(out)
In English, find three dots, anything eager in group, and ending with .bye.
The replacement uses the first match $1 and concats ! using a string template.
An arguably simpler solution:
const str = '...hello world.bye'
const newStr = /...(.+)\.bye/.exec(str)
const formatted = newStr ? newStr[1] + '!' : str
console.log(formatted)
If the string doesn't match the regex it will just return the string.

AngularJS filter to remove a certain regular expression

I am attempting to make an angularJS filter which will remove timestamps that look like this: (##:##:##) or ##:##:##.
This is a filter to remove all letters:
.filter('noLetter', function() {
//this filter removes all letters
return function removeLetters(string){
return string.replace(/[^0-9]+/g, " ");
}
})
This is my attempt to make a filter that removes the time stamps, however it is not working, help is much appreciated.
.filter('noStamps', function () {
return function removeStamps(item) {
return item.replace(/^\([0-9][0-9]:[0-9][0-9]:[0-9][0-9]\)$/i, "");
}
})
My goal is for it to delete the timestamps it finds and leave nothing in their place.
edit based on question in comments:
The time stamps are in the text so it would say "this is an example 21:20:19 of what I am 21:20:20 trying to do 21:20:22"
I would want this to be converted into "this is an example of what I am trying to do" by the filter.
You may use
/\s*\(?\b\d{2}:\d{2}:\d{2}\b\)?/g
See regex demo
Thre main points:
The ^(start of string) and $(end of string) anchors should be removed so that the expression becomes unanchored, and can match input text partially.
Global flag to match all occurrences
Limiting quantifier {2} to shorten the regex (and the use of a shorthand class \d helps shorten it, too)
\)? and \(? are used with ?quantifier to match 1 or 0 occurrences of the round brackets.
\s* in the beginning "trims" the result (as the leading whitespace is matched).
JS snippet:
var str = 'this is an example (21:20:19) of what I am 21:20:20 trying to do 21:20:22';
var result = str.replace(/\s*\(?\b\d{2}:\d{2}:\d{2}\b\)?/g, '');
document.getElementById("r").innerHTML = result;
<div id="r"/>

getting contents of string between digits

have a regex problem :(
what i would like to do is to find out the contents between two or more numbers.
var string = "90+*-+80-+/*70"
im trying to edit the symbols in between so it only shows up the last symbol and not the ones before it. so trying to get the above variable to be turned into 90+80*70. although this is just an example i have no idea how to do this. the length of the numbers, how many "sets" of numbers and the length of the symbols in between could be anything.
many thanks,
Steve,
The trick is in matching '90+-+' and '80-+/' seperately, and selecting only the number and the last constant.
The expression for finding the a number followed by 1 or more non-numbers would be
\d+[^\d]+
To select the number and the last non-number, add parens:
(\d+)[^\d]*([^\d])
Finally add a /g to repeat the procedure for each match, and replace it with the 2 matched groups for each match:
js> '90+*-+80-+/*70'.replace(/(\d+)[^\d]*([^\d])/g, '$1$2');
90+80*70
js>
Or you can use lookahead assertion and simply remove all non-numerical characters which are not last: "90+*-+80-+/*70".replace(/[^0-9]+(?=[^0-9])/g,'');
You can use a regular expression to match the non-digits and a callback function to process the match and decide what to replace:
var test = "90+*-+80-+/*70";
var out = test.replace(/[^\d]+/g, function(str) {
return(str.substr(-1));
})
alert(out);
See it work here: http://jsfiddle.net/jfriend00/Tncya/
This works by using a regular expression to match sequences of non-digits and then replacing that sequence of non-digits with the last character in the matched sequence.
i would use this tutorial, first, then review this for javascript-specific regex questions.
This should do it -
var string = "90+*-+80-+/*70"
var result = '';
var arr = string.split(/(\d+)/)
for (i = 0; i < arr.length; i++) {
if (!isNaN(arr[i])) result = result + arr[i];
else result = result + arr[i].slice(arr[i].length - 1, arr[i].length);
}
alert(result);
Working demo - http://jsfiddle.net/ipr101/SA2pR/
Similar to #Arnout Engelen
var string = "90+*-+80-+/*70";
string = string.replace(/(\d+)[^\d]*([^\d])(?=\d+)/g, '$1$2');
This was my first thinking of how the RegEx should perform, it also looks ahead to make sure the non-digit pattern is followed by another digit, which is what the question asked for (between two numbers)
Similar to #jfriend00
var string = "90+*-+80-+/*70";
string = string.replace( /(\d+?)([^\d]+?)(?=\d+)/g
, function(){
return arguments[1] + arguments[2].substr(-1);
});
Instead of only matching on non-digits, it matches on non-digits between two numbers, which is what the question asked
Why would this be any better?
If your equation was embedded in a paragraph or string of text. Like:
This is a test where I want to clean up something like 90+*-+80-+/*70 and don't want to scrap the whole paragraph.
Result (Expected) :
This is a test where I want to clean up something like 90+80*70 and don't want to scrap the whole paragraph.
Why would this not be any better?
There is more pattern matching, which makes it theoretically slower (negligible)
It would fail if your paragraph had embedded numbers. Like:
This is a paragraph where Sally bought 4 eggs from the supermarket, but only 3 of them made it back in one piece.
Result (Unexpected):
This is a paragraph where Sally bought 4 3 of them made it back in one piece.

Categories

Resources