Capture string between characters and replace - javascript

I'm trying to parse a QML file with Javascript, and make a JSON out of it.
I've encountered a problem that I cannot solve.
I'm trying to replace every string of the file which isn't already between " and put it between double ".
So if I have some strings like
Layout.fillHeight: true
height: 200
color: "transparent"
should become
"Layout.fillHeight": "true"
"height": 200"
"color": "transparent"
Here's the regex I've written, failingly miserably:
/((\S\.\S)|\w+?)(?![^"]*\")/g
(\S.\S)|w+? take every string (considering also words with . between them
Two problems:
If a line contains any string between 2 ", any words of that line is not considered.
With replace() I cannot replace the string because $1 or $2 are not containing the exact string I want to replace.
I'm not great with Regex, so if you guys could help me would be appreciated.

Here is a Notepad++ solution using two replacements. First double quote the keys, if necessary:
Find:
^([^":]+):
Replace:
"$1"
Then quote the values, again if necessary:
Find:
:\s+([^"]+)$
Replace:
"$1"

Something like this?
Gets rid of all the quotes, reinserts at the start and end of each line, and goes on to replace the colon and space with the rest
let string = `Layout.fillHeight: true
height: 200
color: "transparent"`
console.log(string.replace(/\"/g, "").replace(/^|$/gm, "\"").replace(/\:\ /gm, "\": \""))
As an alternative, if they are in an array format to begin with:
function quotify(string) {
let regex = /^\s*"?(.*?)"?:\s*"?(.*?)"?$/,
matches = regex.exec(string);
return `"${matches[1]}": "${matches[2]}"`;
}
let strings = ['Layout.fillHeight: true',
'height: 200',
'color: "transparent"'
],
quotedStrings = [];
strings.forEach((string) => {
quotedStrings.push(quotify(string))
})
let jsonString = JSON.parse(`{${quotedStrings}}`);
console.log(jsonString)

Here is a more involved solution that quotes only strings that aren't already quoted.
var str = `Layout.fillHeight: true
height: 200
color: "transparent"`;
var result = str.split(/\n/).map((v) => {
return v.split(/\s*\:\s*/).map((vv) => {
if(!isNaN(vv) || vv == "true" || vv == "false" || (vv[0] == '"' && vv[vv.length - 1] == '"')){
return vv;
}
return `"${vv}"`;
}).join(":");
}).join(",");
console.log(JSON.parse(`{${result}}`));
I've probably made things more complicated then they have to be and it will most probably fail when processing constructs that I haven't considered.

I tried the REGEX #Tushar provided:
(\S+)\s*:\s*(\S+)
It's the one I was looking for. Thank you for your contribution.

Related

How to check if a string contains a WORD in javascript? [duplicate]

This question already has answers here:
How to check if a string contain specific words?
(11 answers)
Closed 3 years ago.
So, you can easily check if a string contains a particular substring using the .includes() method.
I'm interested in finding if a string contains a word.
For example, if I apply a search for "on" for the string, "phones are good", it should return false. And, it should return true for "keep it on the table".
You first need to convert it into array using split() and then use includes()
string.split(" ").includes("on")
Just need to pass whitespace " " to split() to get all words
This is called a regex - regular expression
You can use of 101regex website when you need to work around them (it helps). Words with custom separators aswell.
function checkWord(word, str) {
const allowedSeparator = '\\\s,;"\'|';
const regex = new RegExp(
`(^.*[${allowedSeparator}]${word}$)|(^${word}[${allowedSeparator}].*)|(^${word}$)|(^.*[${allowedSeparator}]${word}[${allowedSeparator}].*$)`,
// Case insensitive
'i',
);
return regex.test(str);
}
[
'phones are good',
'keep it on the table',
'on',
'keep iton the table',
'keep it on',
'on the table',
'the,table,is,on,the,desk',
'the,table,is,on|the,desk',
'the,table,is|the,desk',
].forEach((x) => {
console.log(`Check: ${x} : ${checkWord('on', x)}`);
});
Explaination :
I am creating here multiple capturing groups for each possibily :
(^.*\son$) on is the last word
(^on\s.*) on is the first word
(^on$) on is the only word
(^.*\son\s.*$) on is an in-between word
\s means a space or a new line
const regex = /(^.*\son$)|(^on\s.*)|(^on$)|(^.*\son\s.*$)/i;
console.log(regex.test('phones are good'));
console.log(regex.test('keep it on the table'));
console.log(regex.test('on'));
console.log(regex.test('keep iton the table'));
console.log(regex.test('keep it on'));
console.log(regex.test('on the table'));
You can .split() your string by spaces (\s+) into an array, and then use .includes() to check if the array of strings has your word within it:
const hasWord = (str, word) =>
str.split(/\s+/).includes(word);
console.log(hasWord("phones are good", "on"));
console.log(hasWord("keep it on the table", "on"));
If you are worried about punctuation, you can remove it first using .replace() (as shown in this answer) and then split():
const hasWord = (str, word) =>
str.replace(/[.,\/#!$%\^&\*;:{}=\-_`~()]/g,"").split(/\s+/).includes(word);
console.log(hasWord("phones are good son!", "on"));
console.log(hasWord("keep it on, the table", "on"));
You can split and then try to find:
const str = 'keep it on the table';
const res = str.split(/[\s,\?\,\.!]+/).some(f=> f === 'on');
console.log(res);
In addition, some method is very efficient as it will return true if any predicate is true.
You can use .includes() and check for the word. To make sure it is a word and not part of another word, verify that the place you found it in is followed by a space, comma, period, etc and also has one of those before it.
A simple version could just be splitting on the whitespace and looking through the resulting array for the word:
"phones are good".split(" ").find(word => word === "on") // undefined
"keep it on the table".split(" ").find(word => word === "on") // "on"
This just splits by whitespace though, when you need parse text (depending on your input) you'll encounter more word delimiters than whitespace. In that case you could use a regex to account for these characters.
Something like:
"Phones are good, aren't they? They are. Yes!".split(/[\s,\?\,\.!]+/)
I would go with the following assumptions:
Words the start of a sentence always have a trailing space.
Words at the end of a sentence always have a preceding space.
Words in the middle of a sentence always have a trailing and preceding space.
Therefore, I would write my code as follows:
function containsWord(word, sentence) {
return (
sentence.startsWith(word.trim() + " ") ||
sentence.endsWith(" " + word.trim()) ||
sentence.includes(" " + word.trim() + " "));
}
console.log(containsWord("test", "This is a test of the containsWord function."));
Try the following -
var mainString = 'codehandbook'
var substr = /hand/
var found = substr.test(mainString)
if(found){
console.log('Substring found !!')
} else {
console.log('Substring not found !!')
}

Return full string if partial string is found Javascript/Jquery

Unable to retrieve full string if partially matched.
Example:
src = 'The expression $ a{\color{blue}{x}}^2 + b{\color{blue}{x}} + c$ is said to be quadratic when TAtrimg001a.svg is \neq 0$'
search for "svg" > should return TAtrimg001a.svg
I am trying to search and find the string "svg". If the "svg" exists then it should return TAtrimg001a.svg not just its location or the word svg itself but the complete svg filename.
In reply to a comment...
I tried finding the match in following differenet ways, but they do really work for my requirment, example:
var res = str.match(/svg/ig);
var res = str.search("svg");
var res = str.indexOf( "svg" )
Straightforward with regex. The string .match method takes a regex and returns either:
null if there was no match.
An array otherwise, where the first element is the entire matched string, and the remaining elements are each respective capture group (if any).
So for this case, you just want the whole match, so just taking that first item should be fine. The example regex below just looks for any string of non-whitespace characters that ends with .svg. You may want to broaden or tighten that to meet your exact use case.
src = 'The expression $ a{\color{blue}{x}}^2 + b{\color{blue}{x}} + c$ is said to be quadratic when TAtrimg001a.svg is \neq 0$'
function findFileName(str, ext) {
const match = str.match(new RegExp(`\\w+\\.${ext}`));
return match && match[0]
}
console.log(findFileName(src, "svg"))
Minor Note: When passing a string to the RegExp constructor, backslashes must be doubled, since the first backslash escapes the second as part of the string.
In ES6 you can do something like const result = str.endsWith(".svg") ? str : null;, which will store in result variable full file name (if it ends with ".svg" part, in other words, has svg format), or null (if it doesn't):
function checkIsFileOfType(str, fileType) {
return str.endsWith("." + fileType) ? str : null;
}
console.log(checkIsFileOfType("TAtrimg001a.svD", "svg"));
console.log(checkIsFileOfType("TAtrimg001a.svg", "svg"));

How to remove \n after JSON.stringfy?

I parse the data from website and try to change to a json object.
Here is my function:
function outPutJSON() {
for (var i = 0; i < movieTitle.length; i++) {
var handleN = movieContent[i];
console.log('===\n');
console.log(handleN);
data.movie.push({
mpvieTitle: movieTitle[i],
movieEnTitle: movieEnTitle[i],
theDate: theDate[i],
theLength: theLength[i],
movieVersion: movieVersion[i],
youtubeId: twoId[i],
content: movieContent[i]
});
};
return JSON.stringify(data);
}
console.log will print movieContent[0] like:
but i return JSON.stringfy(data);
it will become:
There are so many /n i want to remove it.
I try to change return JSON.stringfy(data); to this:
var allMovieData = JSON.stringify(data);
allMovieData = allMovieData.replace(/\n/g, '');
return allMovieData;
It's not working the result is the same.
How to remove /n when i use JSON.stringfy() ?
Any help would be appreciated . Thanks in advance.
In your data screenshots, you literally see "\n".
This probably means that the actual string doesn't contain a newline character (\n), but a escaped newline character (\\n).
A newline character would have been rendered as a linebreak. You wouldn't see the \n.
To remove those, use .replace(/\\n/g, '') instead of .replace(/\n/g, '')
just :=>
JSON.stringify(JSON.parse(<json object>))
JSON.stringify converts new lines (\n) and tab (\t) chars into string, so, when you will try to parse it, the string will contain those again.
So, you need to search the string \n, you can do that with something like that.
const stringWithNewLine = {
x: `this will conatin
new lines`
};
const json = JSON.stringify(stringWithNewLine);
console.log(json.replace(/\\n/g, ''))
I know this is an old question but it is always good to have options. You can use a string literal as a simple wrapper. The string literal will honor the string's line breaks, empty spaces etc. Like:
let jsonAsPrettyString = `${JSON.stringify(jsonObject, null, 2)}`;

Javascript replace regex any character

I am trying to replace something like '?order=height' and I know it can be easily done like this:
data = 'height'
x = '?order=' + data
x.replace('?order=' + data, '')
But the problem is that question mark can sometimes be ampersand.. What I really wish to do is make blank whether the first character is ampersand or question mark so basically whether
?order=height
&order=height
can be made a blank string
x.replace(/[&?]order=height/, '')
If data is string variable
x.replace(/[&?]order=([^&=]+)/, '')
Use regex for that .replace(/[?&]order=height/, '')
[?&] means any character from this list.
/ is start and end delimiter.
Please note that pattern is not enclosed as string with ' or ".
This is how you may do it. Create a RegExp object with
"[&?]order=" + match
and replace with "" using String.prototype.replace
function replace(match, str) {
regex = new RegExp("[&?]order=" + match,"g")
return str.replace(regex, "")
}
console.log(replace("height", "Yo &order=height Yo"))
console.log(replace("weight", "Yo ?order=weight Yo"))
console.log(replace("age", "Yo ?order=age Yo"))

startswith in javascript error

I'm using startswith reg exp in Javascript
if ((words).match("^" + string))
but if I enter the characters like , ] [ \ /, Javascript throws an exception.
Any idea?
If you're matching using a regular expression you must make sure you pass a valid Regular Expression to match(). Check the list of special characters to make sure you don't pass an invalid regular expression. The following characters should always be escaped (place a \ before it): [\^$.|?*+()
A better solution would be to use substr() like this:
if( str === words.substr( 0, str.length ) ) {
// match
}
or a solution using indexOf is a (which looks a bit cleaner):
if( 0 === words.indexOf( str ) ) {
// match
}
next you can add a startsWith() method to the string prototype that includes any of the above two solutions to make usage more readable:
String.prototype.startsWith = function(str) {
return ( str === this.substr( 0, str.length ) );
}
When added to the prototype you can use it like this:
words.startsWith( "word" );
One could also use indexOf to determine if the string begins with a fixed value:
str.indexOf(prefix) === 0
If you want to check if a string starts with a fixed value, you could also use substr:
words.substr(0, string.length) === string
If you really want to use regex you have to escape special characters in your string. PHP has a function for it but I don't know any for JavaScript. Try using following function that I found from [Snipplr][1]
function escapeRegEx(str)
{
var specials = new RegExp("[.*+?|()\\[\\]{}\\\\]", "g"); // .*+?|()[]{}\
return str.replace(specials, "\\$&");
}
and use as
var mystring="Some text";
mystring=escapeRegEx(mystring);
If you only need to find strings starting with another string try following
String.prototype.startsWith=function(string) {
return this.indexOf(string) === 0;
}
and use as
var mystring="Some text";
alert(mystring.startsWith("Some"));

Categories

Resources