In Javascript I have several words separated by either a dot or one ore more whitepaces (or the end of the string).
I'd like to replace certain parts of it to insert custom information at the appropriate places.
Example:
var x = "test1.test test2 test3.xyz test4";
If there's a dot it should be replaced with ".X_"
If there's one or more space(s) and the word before does not contain a dot, replace with ".X "
So the desired output for the above example would be:
"test1.X_test test2.X test3.X_xyz test4.X"
Can I do this in one regex replace? If so, how?
If I need two or more what would they be?
Thanks a bunch.
Try this:
var str = 'test1.test test2 test3.xyz test4';
str = str.replace(/(\w+)\.(\w+)/g, '$1.X_$2');
str = str.replace(/( |^)(\w+)( |$)/g, '$1$2.X$3');
console.log(str);
In the first replace it replaces the dot in the dotted words with a .X_, where a dotted word is two words with a dot between them.
In the second replace it adds .X to words that have no dot, where words that have no dot are words that are preceded by a space OR the start of the string and are followed by a space OR the end of the string.
To answer this:
If there's a dot it should be replaced with ".X_"
If there's one or more spaces it should be replaced with ".X"
Do this:
x.replace(/\./g, '.X_').replace(/\s+/g, '.X');
Edit: To get your desired output (rather than your rules), you can do this:
var words = x.replace(/\s+/g, ' ').split(' ');
for (var i = 0, l = words.length; i < l; i++) {
if (words[i].indexOf('.') === -1) {
words[i] += ".X";
}
else {
words[i] = words[i].replace(/\./g, '.X_');
}
}
x = words.join(' ');
Basically...
Strip all multiple spaces and create an array of "words"
Loop through each word.
If it doesn't have a period in it, then add ".X" to the end of the word
Else, replace the periods with ".X_"
Join the "words" back into a string and separate it by spaces.
Edit 2:
Here's a solution using only javascript's replace function:
x.replace(/\s+/g, ' ') // replace multiple spaces with one space
.replace(/\./g, '.X_') // replace dots with .X_
// find words without dots and add a ".X" to the end
.replace(/(^|\s)([^\s\.]+)($|\s)/g, "$1$2.X$3");
Related
Here, I want to give each character a space except for the last alphabetic one:
var str = "test"
var result = "";
for (var i = 0; i < str.length; i++) {
result += (/*condition*/) ? str[i]
: str[i] + " ";
}
console.log(result);
So it prints "t e s t".
I tried this (i === str.length - 1) but it didn't work when a string had period(.) as it's last character ("test.") while I wanna target only alphabetics.
You can use a regular expression to remove all non-alphabetical characters first, and then do a split/join combination to insert the spaces (or use another regex):
var str = "don't test.";
var result = str.replace(/[^a-z]/gi, '').split('').join(' ');
console.log(result);
"testasdf. asdf asdf asd.d?".replace(/./g,"$& ").replace(/([A-Za-z]) ([^A-Za-z]*)$/, '$1$2')
the first replace add a space to all char
the second replace removes the space after the last letter
console.log("testasdf?".replace(/./g,"$& ").replace(/([A-Za-z]) ([^A-Za-z]*)$/, '$1$2'));
console.log("Super test ! Yes".replace(/./g,"$& ").replace(/([A-Za-z]) ([^A-Za-z]*)$/, '$1$2'));
There is such a feature like lookahead assertions.
So it could be
str.replace(/(\w)(?=.*\w)/, "$1")
Using a regex replace function, you can space out all of your characters like this:
"test string, with several words.".replace(/\w{2,}/g, match => match.split('').join(' '))
Explanation
\w{2,} match 2 or more alphabetic characters
match.split('').join(' ') split each match into characters, and rejoin with spaces between
I am given a string as input, and the last letter in every word of the string should be capitalized, and then it is formed into their own div.
The one thing that I am finding tricky is that no matter what the string is there should always be enough divs to be separated, which to me means that I need to have a loop that generates it, which is what I am not sure how to write that logic.
I need this to be the output:
<div>
partY
</div>
<div>
likE
</div>
<div>
itS
</div>
<div>
2015
</div>
This is what I have so far:
function yay (input) {
input = input.toLowerCase().split("").reverse().join("").split(" ");
for(var i = 1 ; i < input.length ; i++){
var len = input[i].length-1;
input[i] = input[i].substring(0, len) + input[i].substr(len).toUpperCase();
}
return input .reverse().join(" ");
}
console.log(yay("Party like its 2015"));
Well, just a few minor changes to your code, which was on the right track... I basically removed the unnecessary reversing and wrapped each word in a div in the loop and viola:
function yay (input) {
input = input.toLowerCase().split(" ");
for(var i = 0 ; i < input.length ; i++){
var len = input[i].length-1;
input[i] = '<div>'+input[i].substring(0, len) + input[i].substr(len).toUpperCase()+'</div>';
}
return input.join("");
}
console.log(yay("Party like its 2015"));
document.write(yay("Party like its 2015"));
Output:
<div>partY</div><div>likE</div><div>itS</div><div>2015</div>
You can use document.createElement('div') and document.createTextNode('text') to simply get what you need.
You can return the content element directly to append to your node of your need, or you can use the innerHTML to do some text manipulations.
EDIT
Modified, I totally missed the last character needs to be uppercase
function yay(str) {
var arr = str.split(' ');
var content = document.createElement('div');
for(var part in arr) {
var sub = document.createElement('div');
var lastChar = arr[part].charAt(arr[part].length-1).toUpperCase();
var appendStr = arr[part].substring(0,arr[part].length-1);
sub.appendChild(document.createTextNode(appendStr+lastChar));
content.appendChild(sub);
}
return content.innerHTML;
}
console.log(yay("Party like its 2015"));
How about this:
function capitalizeLastLetter(input) {
return input.substring(0, input.length - 1) + input.charAt(input.length - 1).toUpperCase();
}
function yay(input) {
return input
.toLocaleLowerCase()
.split(" ")
.map(function(s){ return "<div>" + capitalizeLastLetter(s) + "</div>"; })
.join("");
}
console.log(yay("Party like its 2015"));
document.write(yay("Party like its 2015"));
Remixes this answer on how to capitalize the first letter of a word.
Add newlines where appropriate if you actually need those in your output.
You might want to use String.prototype.replace and feed it with a regular expression:
function yay(input) {
return input.
toLocaleLowerCase().
replace(/([^\s.,:;!?]*)([^\s.,:;!?")])([^\s]*)/g,
function(match, sub1, sub2, sub3) {
return '<div>' + sub1 + sub2.toLocaleUpperCase() + sub3 + '</div>';
});
}
The regex captures zero or more (because regular expressions are "greedy" by default, the algorithm will capture as many characters as it can) non-whitespace (to support alphabets other than Latin) and non-punctuation characters and exactly one non-whitespace/non-punctuation character following them (the last letter in the word, even if it's the only letter forming the word). The last group is zero or more of the previously specified punctuation marks (.,:;!?")). What it says is "non-whitespace character", but the presence of the two previous parenthesized groups implies that it must be a punctuation mark.
The replacement callback here uses four arguments, one (unused in this case) for the entire match and three for submatches corresponding to the parenthesized groups in the regex.
The value returned from the callback replaces the entire match in each successive replacement cycle (abcd in abcd efgh will be replaced with <div>abcD</div> and so on, note that whitespaces will be preserved).
In the callback function, the first submatch consists of all the letters in a word except the last one. It is returned as is, but the other match (which is the last letter) is capitalized. Optionally, a punctuation mark is appended if present in the original input. Everything is then wrapped in the <div> HTML tag and returned.
You can assign the value returned by the yay function to the innerHTML property of an HTML element, for example:
document.querySelector('#container').innerHTML = yay('Party like its 2015');
Spaces present in the input will remain. There is no need to replace them with new line characters, as all whitespaces are treated equally in HTML and will result in the same behavior.
Edit:
Now you can pass input containing punctuation to the function. The following line:
yay('Hello there, how about using some punctuation? "Quote" (Parentheses) ("What?")')
will result in:
'<div>hellO</div> <div>therE,</div> <div>hoW</div> <div>abouT</div> <div>usinG</div> <div>somE</div> <div>punctuatioN?</div> <div>"quotE"</div> <div>(parentheseS)</div> <div>("whaT?")</div>'
I am trying to remove some spaces from a few dynamically generated strings. Which space I remove depends on the length of the string. The strings change all the time so in order to know how many spaces there are, I iterate over the string and increment a variable every time the iteration encounters a space. I can already remove all of a specific type of character with str.replace(' ',''); where 'str' is the name of my string, but I only need to remove a specific occurrence of a space, not all the spaces. So let's say my string is
var str = "Hello, this is a test.";
How can I remove ONLY the space after the word "is"? (Assuming that the next string will be different so I can't just write str.replace('is ','is'); because the word "is" might not be in the next string).
I checked documentation on .replace, but there are no other parameters that it accepts so I can't tell it just to replace the nth instance of a space.
If you want to go by indexes of the spaces:
var str = 'Hello, this is a test.';
function replace(str, indexes){
return str.split(' ').reduce(function(prev, curr, i){
var separator = ~indexes.indexOf(i) ? '' : ' ';
return prev + separator + curr;
});
}
console.log(replace(str, [2,3]));
http://jsfiddle.net/96Lvpcew/1/
As it is easy for you to get the index of the space (as you are iterating over the string) , you can create a new string without the space by doing:
str = str.substr(0, index)+ str.substr(index);
where index is the index of the space you want to remove.
I came up with this for unknown indices
function removeNthSpace(str, n) {
var spacelessArray = str.split(' ');
return spacelessArray
.slice(0, n - 1) // left prefix part may be '', saves spaces
.concat([spacelessArray.slice(n - 1, n + 1).join('')]) // middle part: the one without the space
.concat(spacelessArray.slice(n + 1)).join(' '); // right part, saves spaces
}
Do you know which space you want to remove because of word count or chars count?
If char count, you can Rafaels Cardoso's answer,
If word count you can split them with space and join however you want:
var wordArray = str.split(" ");
var newStr = "";
wordIndex = 3; // or whatever you want
for (i; i<wordArray.length; i++) {
newStr+=wordArray[i];
if (i!=wordIndex) {
newStr+=' ';
}
}
I think your best bet is to split the string into an array based on placement of spaces in the string, splice off the space you don't want, and rejoin the array into a string.
Check this out:
var x = "Hello, this is a test.";
var n = 3; // we want to remove the third space
var arr = x.split(/([ ])/); // copy to an array based on space placement
// arr: ["Hello,"," ","this"," ","is"," ","a"," ","test."]
arr.splice(n*2-1,1); // Remove the third space
x = arr.join("");
alert(x); // "Hello, this isa test."
Further Notes
The first thing to note is that str.replace(' ',''); will actually only replace the first instance of a space character. String.replace() also accepts a regular expression as the first parameter, which you'll want to use for more complex replacements.
To actually replace all spaces in the string, you could do str.replace(/ /g,""); and to replace all whitespace (including spaces, tabs, and newlines), you could do str.replace(/\s/g,"");
To fiddle around with different regular expressions and see what they mean, I recommend using http://www.regexr.com
A lot of the functions on the JavaScript String object that seem to take strings as parameters can also take regular expressions, including .split() and .search().
I am trying to use XRegExp to test if a string is a valid word according to these criteria:
The string begins with one or more Unicode letters, followed by
an apostrophe (') followed by one or more Unicode letters, repeated 0 or more times.
The string ends immediately after the matched pattern.
That is, it will match these terms
Hello can't Alah'u'u'v'oo O'reilly
but not these
eatin' 'sup 'til
I am trying this pattern,
^(\\p{L})+('(\\p{L})+)*$
but it won't match any words that contain apostrophes. What am I doing wrong?
EDIT: The code using the regex
var separateWords = function(text) {
var word = XRegExp("(\\p{L})+('(\\p{L})+)*$");
var splits = [];
for (var i = 0; i < text.length; i++) {
var item = text[i];
while (i + 1 < text.length && word.test(item + text[i + 1])) {
item += text[i + 1];
i++;
}
splits.push(item);
}
return splits;
};
I think you will need to omit the string start/end anchors to match single words:
"(\\p{L})+('(\\p{L})+)*"
Also I'm not sure what those capturing groups are needed for (that may depend on your application), but you could shorten them to
"\\p{L}+('\\p{L}+)*"
Try this regex:
^[^'](?:[\w']*[^'])?$
First it checks to ensure the first character is not an apostrophe. Then it either gets any number of word characters or apostrophes followed by anything other than an apostrophe, or it gets nothing (one-letter word).
I need to split a keyword string and turn it into a comma delimited string. However, I need to get rid of extra spaces and any commas that the user has already input.
var keywordString = "ford tempo, with,,, sunroof";
Output to this string:
ford,tempo,with,sunroof,
I need the trailing comma and no spaces in the final output.
Not sure if I should go Regex or a string splitting function.
Anyone do something like this already?
I need to use javascript (or JQ).
EDIT (working solution):
var keywordString = ", ,, ford, tempo, with,,, sunroof,, ,";
//remove all commas; remove preceeding and trailing spaces; replace spaces with comma
str1 = keywordString.replace(/,/g , '').replace(/^\s\s*/, '').replace(/\s\s*$/, '').replace(/[\s,]+/g, ',');
//add a comma at the end
str1 = str1 + ',';
console.log(str1);
You will need a regular expression in both cases. You could split and join the string:
str = str.split(/[\s,]+/).join();
This splits on and consumes any consecutive white spaces and commas. Similarly, you could just match and replace these characters:
str = str.replace(/[\s,]+/g, ',');
For the trailing comma, just append one
str = .... + ',';
If you have preceding and trailing white spaces, you should remove those first.
Reference: .split, .replace, Regular Expressions
In ES6:
var temp = str.split(",").map((item)=>item.trim());
In addition to Felix Kling's answer
If you have preceding and trailing white spaces, you should remove
those first.
It's possible to add an "extension method" to a JavaScript String by hooking into it's prototype. I've been using the following to trim preceding and trailing white-spaces, and thus far it's worked a treat:
// trims the leading and proceeding white-space
String.prototype.trim = function()
{
return this.replace(/^\s\s*/, '').replace(/\s\s*$/, '');
};
I would keep it simple, and just match anything not allowed instead to join on:
str.split(/[^a-zA-Z-]+/g).filter(v=>v);
This matches all the gaps, no matter what non-allowed characters are in between. To get rid of the empty entry at the beginning and end, a simple filter for non-null values will do. See detailed explanation on regex101.
var str = ", ,, ford, tempo, with,,, sunroof,, ,";
var result = str.split(/[^a-zA-Z-]+/g).filter(v=>v).join(',');
console.info(result);
let query = "split me by space and remove trailing spaces and store in an array ";
let words = query.trim().split(" ");
console.log(words)
Output :
[
'split', 'me', 'by', 'space','and','remove', 'trailing', 'spaces', 'and', 'store', 'in', 'an', 'array'
]
If you just want to split, trim and join keeping the whitespaces, you can do this with lodash:
// The string to fix
var stringToFix = "The Wizard of Oz,Casablanca,The Green Mile";
// split, trim and join back without removing all the whitespaces between
var fixedString = _.map(stringToFix.split(','), _.trim).join(' == ');
// output: "The Wizard of Oz == Casablanca == The Green Mile"
console.log(fixedString);
<script src="https://cdn.jsdelivr.net/lodash/4.16.3/lodash.min.js"></script>