Javascript cut string by begin and end and store in array - javascript

I need a algorithm which is doing something like this:
var example = "Hello $$user$$ your real name is $$realname$$. Have a good day"
Output --> ["Hello ", "$$user$$", " your real name is ", "$$realname$$", ". Have a good day"]
Hence, split the part by a selected character and put them together in a string array. Can someone help me out?
I'm looking for a solution with JavaScript/jQuery

It seems you want to split by pattern $$...$$; You could use /(\$\$.*?\$\$)/; To keep the pattern in the result, you can make it a capture group, and also make it lazy (?) so that it will split with the shortest length pattern matched:
example.split(/(\$\$.*?\$\$)/)
#[ 'Hello ',
# '$$user$$',
# ' your real name is ',
# '$$realname$$',
# '. Have a good day' ]

Yes, this is possible with JavaScript itself... Slightly tricky, but yes.
var strings = [], tokens = [];
var str = "Hello $$user$$ your real name is $$realname$$. Have a good day".replace(/\$\$(.*?)\$\$/g, "\$\$TOKEN$1\$\$").split("$");
for (var i = 0; i < str.length; i++) {
if (str[i].indexOf("TOKEN") === 0) {
// This is a token.
tokens.push(str[i].replace("TOKEN", ""));
} else {
strings.push(str[i]);
}
}
str = str.map(function (v) {
if (v.indexOf("TOKEN") === 0)
return "$$" + v.replace("TOKEN", "") + "$$";
return v;
});
console.log(str);
console.log(strings);
console.log(tokens);
The above code will split everything into tokens. And on top of it, it also separates the strings and tokens out. The above one gives as per your requirement:
[
"Hello ",
"$$user$$",
" your real name is ",
"$$realname$$",
". Have a good day"
]
Kindly note, there's nothing like {value, value}, there's only [value, value].

String.split()
The split() method splits a String object into an array of strings by separating the string into substrings.
var example = "Hello $$user$$ your real name is $$realname$$. Have a good day";
var exSplit = example.split("$$");
var userIdx = exSplit.indexOf("user");
var nameIdx = exSplit.indexOf("realname");
document.querySelector(".user").innerHTML = exSplit[userIdx];
document.querySelector(".name").innerHTML = exSplit[nameIdx];
<div class="user"></div>
<div class="name"></div>
Though, if I may suggest, variables can handle this type of operation without all of the hassle.

Related

Javascript splitting string in to two parts number and text safely

I was wondering if there is a safe way (if the data is coming from users) to get the string and the number separated - for example "something-55", "something-124", "something-1291293"
I would want:
something and
55
something and
124
something and
1291293
I mean by a 'safe way' is to be certain I am getting only the number on the end.. if the data is coming from the users "something" could be anything some-thing-55 for example..
I'm looking for a robust way.
try this, working.
var string = 'something-456';
var array = string.split('-');
for (var i = 0;i<array.length;i++){
var number = parseFloat(array[i]);
if(!isNaN(number)){
var myNumber = number;
var mySomething = array[i - 1];
console.log('myNumber= ' + myNumber);
console.log('mySomething= ' + mySomething);
}
}
Can you try this?
var input='whatever-you-want-to-parse-324';
var sections=input.split(/[\w]+-/);
alert(sections[sections.length-1]);
You can use substr along with lastIndexOf:
var str = "something-somethingelse-55",
text = str.substr(0, str.lastIndexOf('-')),
number = str.substr(str.lastIndexOf('-') + 1);
console.log(text + " and " + number);
Fiddle Demo
All though it's a tad late, this would be the most restrictive solution:
var regex = /^([-\w])+?-(\d+)$/,
text = "foo-123",
match = test.match(regex);
You will get a match object back with the following values:
[ "foo-123", "foo", "123" ]
It's a very strict match so that " foo-123" and "foo-123 " would not match, and it requires the string to end in one or more digits.

Change occurrences of sum(something) to something_sum

Admittedly I'm terrible with RegEx and pattern replacements, so I'm wondering if anyone can help me out with this one as I've been trying now for a few hours and in the process of pulling my hair out.
Examples:
sum(Sales) needs to be converted to Sales_sum
max(Sales) needs to be converted to Sales_max
min(Revenue) needs to be converted to Revenue_min
The only available prefixed words will be sum, min, max, avg, xcount - not sure if this makes a difference in the solution.
Hopefully that's enough information to kind of show what I'm trying to do. Is this possible via RegEx?
Thanks in advance.
There are a few possible ways, for example :
var str = "min(Revenue)";
var arr = str.match(/([^(]+)\(([^)]+)/);
var result = arr[2]+'_'+arr[1];
result is then "Revenue_min".
Here's a more complex example following your comment, handling many matches and lowercasing the verb :
var str = "SUM(Sales) + MIN(Revenue)";
var result = str.replace(/\b([^()]+)\(([^()]+)\)/g, function(_,a,b){
return b+'_'+a.toLowerCase()
});
Result : "Sales_sum + Revenue_min"
Try with:
var input = 'sum(Sales)',
matches = input.match(/^([^(]*)\(([^)]*)/),
output = matches[2] + '_' + matches[1];
console.log(output); // Sales_sum
Also:
var input = 'sum(Sales)',
output = input.replace(/^([^(]*)\(([^)]*)\)/, '$2_$1');
You can use replace with tokens:
'sum(Sales)'.replace(/(\w+)\((\w+)\)/, '$2_$1')
Using a whitelist for your list of prefixed words:
output = input.replace(/\b(sum|min|max|avg|xcount)\((.*?)\)/gi,function(_,a,b) {
return b.toLowerCase()+"_"+a;
});
Added \b, a word boundary. This prevents something like "haxcount(xorz)" from becoming "haxorz_xcount"

javascript - replacing spaces with a string

I'm new to Javascript and need a bit of help with program on a college course to replace all the spaces in a string with the string "spaces".
I've used the following code but I just can't get it to work:
<html>
<body>
<script type ="text/javascript">
// Program to replace any spaces in a string of text with the word "spaces".
var str = "Visit Micro soft!";
var result = "";
For (var index = 0; index < str.length ; index = index + 1)
{
if (str.charAt(index)= " ")
{
result = result + "space";
}
else
{
result = result + (str.charAt(index));
}
}
document.write(" The answer is " + result );
</script>
</body>
</html>
For
isn't capitalized:
for
and
str.charAt(index)= " "
needs to be:
str.charAt(index) == " "
JavaScript Comparison Operators
for loops
As others have mentioned there are a few obvious errors in your code:
The control flow keyword for must be all lower-case.
The assignment operator = is different than the comparison operators == and ===.
If you are allowed to use library functions then this problem looks like a good fit for the JavaScript String.replace(regex,str) function.
Another option would be to skip the for cycle altogether and use a regular expression:
"Visit Micro soft!".replace(/(\s)/g, '');
Try this:
str.replace(/(\s)/g, "spaces")
Or take a look at this previous answer to a similar question: Fastest method to replace all instances of a character in a string Hope this help
You should use the string replace method. Inconvenienty, there is no replaceAll, but you can replace all anyways using a loop.
Example of replace:
var word = "Hello"
word = word.replace('e', 'r')
alert(word) //word = "Hrllo"
The second tool that will be useful to you is indexOf, which tells you where a string occurs in a string. It returns -1 if the string does not appear.
Example:
var sentence = "StackOverflow is helpful"
alert(sentence.indexOf(' ')) //alerts 13
alert(sentence.indexOf('z')) //alerts -1

Regex, grab only one instance of each letter

I have a paragraph that's broken up into an array, split at the periods. I'd like to perform a regex on index[i], replacing it's contents with one instance of each letter that index[i]'s string value has.
So; index[i]:"This is a sentence" would return --> index[i]:"thisaenc"
I read this thread. But i'm not sure if that's what i'm looking for.
Not sure how to do this in regex, but here's a very simple function to do it without using regex:
function charsInString(input) {
var output='';
for(var pos=0; pos<input.length; pos++) {
char=input.charAt(pos).toLowerCase();
if(output.indexOf(char) == -1 && char != ' ') {output+=char;}
}
return output;
}
alert(charsInString('This is a sentence'));
As I'm pretty sure what you need cannot be achieved using a single regular expression, I offer a more general solution:
// collapseSentences(ary) will collapse each sentence in ary
// into a string containing its constituent chars
// #param {Array} the array of strings to collapse
// #return {Array} the collapsed sentences
function collapseSentences(ary){
var result=[];
ary.forEach(function(line){
var tmp={};
line.toLowerCase().split('').forEach(function(c){
if(c >= 'a' && c <= 'z') {
tmp[c]++;
}
});
result.push(Object.keys(tmp).join(''));
});
return result;
}
which should do what you want except that the order of characters in each sentence cannot be guaranteed to be preserved, though in most cases it is.
Given:
var index=['This is a sentence','This is a test','this is another test'],
result=collapseSentences(index);
result contains:
["thisaenc","thisae", "thisanoer"]
(\w)(?<!.*?\1)
This yields a match for each of the right characters, but as if you were reading right-to-left instead.
This finds a word character, then looks ahead for the character just matched.
Nevermind, i managed:
justC = "";
if (color[i+1].match(/A/g)) {justC += " L_A";}
if (color[i+1].match(/B/g)) {justC += " L_B";}
if (color[i+1].match(/C/g)) {justC += " L_C";}
if (color[i+1].match(/D/g)) {justC += " L_D";}
if (color[i+1].match(/E/g)) {justC += " L_E";}
else {color[i+1] = "L_F";}
It's not exactly what my question may have lead to belive is what i wanted, but the printout for this is what i was after, for use in a class: <span class="L_A L_C L_E"></span>
How about:
var re = /(.)((.*?)\1)/g;
var str = 'This is a sentence';
x = str.toLowerCase();
x = x.replace(/ /g, '');
while(x.match(re)) {
x=x.replace(re, '$1$3');
}
I don't think this can be done in one fell regex swoop. You are going to need to use a loop.
While my example was not written in your language of choice, it doesn't seem to use any regex features not present in javascript.
perl -e '$foo="This is a sentence"; while ($foo =~ s/((.).*?)\2/$1/ig) { print "<$1><$2><$foo>\n"; } print "$foo\n";'
Producing:
This aenc

Replacing multiple patterns in a block of data

I need to find the most efficient way of matching multiple regular expressions on a single block of text. To give an example of what I need, consider a block of text:
"Hello World what a beautiful day"
I want to replace Hello with "Bye" and "World" with Universe. I can always do this in a loop ofcourse, using something like String.replace functions availiable in various languages.
However, I could have a huge block of text with multiple string patterns, that I need to match and replace.
I was wondering if I can use Regular Expressions to do this efficiently or do I have to use a Parser like LALR.
I need to do this in JavaScript, so if anyone knows tools that can get it done, it would be appreciated.
Edit
6 years after my original answer (below) I would solve this problem differently
function mreplace (replacements, str) {
let result = str;
for (let [x, y] of replacements)
result = result.replace(x, y);
return result;
}
let input = 'Hello World what a beautiful day';
let output = mreplace ([
[/Hello/, 'Bye'],
[/World/, 'Universe']
], input);
console.log(output);
// "Bye Universe what a beautiful day"
This has as tremendous advantage over the previous answer which required you to write each match twice. It also gives you individual control over each match. For example:
function mreplace (replacements, str) {
let result = str;
for (let [x, y] of replacements)
result = result.replace(x, y);
return result;
}
let input = 'Hello World what a beautiful day';
let output = mreplace ([
//replace static strings
['day', 'night'],
// use regexp and flags where you want them: replace all vowels with nothing
[/[aeiou]/g, ''],
// use captures and callbacks! replace first capital letter with lowercase
[/([A-Z])/, $0 => $0.toLowerCase()]
], input);
console.log(output);
// "hll Wrld wht btfl nght"
Original answer
Andy E's answer can be modified to make adding replacement definitions easier.
var text = "Hello World what a beautiful day";
text.replace(/(Hello|World)/g, function ($0){
var index = {
'Hello': 'Bye',
'World': 'Universe'
};
return index[$0] != undefined ? index[$0] : $0;
});
// "Bye Universe what a beautiful day";
You can pass a function to replace:
var hello = "Hello World what a beautiful day";
hello.replace(/Hello|World/g, function ($0, $1, $2) // $3, $4... $n for captures
{
if ($0 == "Hello")
return "Bye";
else if ($0 == "World")
return "Universe";
});
// Output: "Bye Universe what a beautiful day";
An improved answer:
var index = {
'Hello': 'Bye',
'World': 'Universe'
};
var pattern = '';
for (var i in index) {
if (pattern != '') pattern += '|';
pattern += i;
}
var text = "Hello World what a beautiful day";
text.replace(new RegExp(pattern, 'g'), function($0) {
return index[$0] != undefined ? index[$0] : $0;
});
If the question is how to replace multiple generic patterns with corresponding replacements - either strings or functions, it's quite tricky because of special characters, capturing groups and backreference matching.
You can use https://www.npmjs.com/package/union-replacer for this exact purpose. It is basically a string.replace(regexp, string|function) counterpart, which allows multiple replaces to happen in one pass while preserving full power of string.replace(...).
Disclosure: I am the author and the library was developed because we had to support user-configured replaces.
A common task involving replacing a number of patterns is making a user's or other string "safe" for rendering on Web pages, which means preventing HTML tags from being active. This can be done in JavaScript using HTML entities and the forEach function, allowing a set of exceptions (that is, a set of HTML tags that will be allowed to render).
This is a common task, and here is a fairly brief way to accomplish it:
// Make a string safe for rendering or storing on a Web page
function SafeHTML(str)
{
// Make all HTML tags safe
let s=str.replace(/</gi,'<');
// Allow certain safe tags to be rendered
['br','strong'].forEach(item=>
{
let p=new RegExp('<(/?)'+item+'>','gi');
s=s.replace(p,'<$1'+item+'>');
});
return s;
} // SafeHTML

Categories