Move leading or trailing whitespaces in string out of asterisks - javascript

I'm trying to transform invalid markdown for bold words into valid one. For the major part I've figured out how to get the words surrounded by asterisks but now I'm trying to find a way to transform this:
**A bold text **
Into this:
**A bold text**
Moving the trailing whitespace two steps to the right, out of the asterisks.
Same would be needed for leading whitespaces.
Any suggestions? Thanks!
Edit: I'd need to keep the whitespace but outside the bold syntax, not remove it.

let str = '**A bold text **';
let frontSpace = str.match(/\W{1,}/).toString().replace('**','');
let rearSpace = str.match(/\W{2,}$/).toString().replace('**','');
console.log(frontSpace + '**' + str.replace(/\*\*/g,'').trim() + '**' +rearSpace);

You can use the combination of split and trim to build the expected string as shown below.
const word1 = '** Hello Keel **';
const wordArr1 = word1.split('**');
console.log(wordArr1[0] + '**' + wordArr1[1].trim() + '**' + wordArr1[2]);
This would also work for Hello ** Keel **, Welcome to Stack Overflow

You can use replace
\*{2}(\s*)([^*]+?)(\s*)\*{2}
let str = `**A bold text **`
let replacer = (str) => {
return str.replace(/\*{2}(\s*)([^*]+?)(\s*)\*{2}/g, (m, g1,g2,g3) => {
return `${g1}**${g2}**${g3}`
})
}
console.log(replacer(str))
console.log(replacer("some random string ** some text **"))

Related

capitalize first letter of word more than 3 character Regex

I code something in React and i want to use Regex to capitalize first letter of word more than 3 letters with Regex, but I'am lost with Regex, i found lot of things but nothings works. Any advice?
Regex example but dont work
"^[a-z](?=[a-zA-Z'-]{3})|\b[a-zA-Z](?=[a-zA-Z'-]{3,}$)|['-][a-z]"
\w{4,} - this regex expression will match all words that have more than 3 letters
let str = "this is Just an long string with long and short words";
const matches = str.matchAll(/\w{4,}/g);
for(match of matches) {
str = str.substring(0, match.index) + match[0].charAt(0).toUpperCase() + match[0].slice(1) + str.substring(match.index + match[0].length);
}
console.log(str);
Here are two example. One for sentences (like AidOnline01's answer, but using String#replaceAll) and a second one when using words only.
However, when using words only, you can also check for the length instead of using a regexp.
const sentence = "This is a sentence with a few words which should be capitialized";
const word = "capitialized";
// use String#replaceAll to replace all words in a sentence
const sentenceResult = sentence.replaceAll(/\w{4,}/g, word => word[0].toUpperCase() + word.slice(1));
// use String#replace for a single word
const wordResult = word.replace(/\w{4,}/, word => word[0].toUpperCase() + word.slice(1));
console.log(sentenceResult);
console.log(wordResult);

code to replace all spaces except the first and last with %20

urlEncode = function(text) {
let str = text.split(' ').join('%20');
return str;
};
The above is working but If a string has a space in the beginning or end it should not replace %20 .The above is replacing every space .I tried using loops ..
for(let i = 1 ;i < text.length-1;i++){
if(text[i]===''){
text[i]='%20';
}
}
return text;
this one is returning the original text with no change.
A regular expression to match a space not at the beginning nor end of the string would work.
const urlEncode = text => text.replace(/(?!^) (?!$)/g, '%20');
(?!^) - not at the beginning
(?!$) - not at the end
Another method would be to turn the text string into an array so that assignment to its indicies using your second snippet would work. Replace the indicies as needed, then join into a string again and return.
or, you can test another
const urlEncode = text => text.replace(/[^\s]\s[^\s$]/g, '%20')

Replace Regex Symbols + Blank Space

There is any way to make a regex to replace symbols + blank space?
Im using:
const cleanMask = (value) => {
const output = value.replace(/[_()-]/g, "").trim();
return output;
}
let result = cleanMask('this (contains parens) and_underscore, and-dash')
console.log(result)
Its it right?
Your current code will replace all occurrences of characters _, (, ) and - with an empty string and then trim() whitespace from the beginning and end of the result.
If you want to remove ALL whitespace, you can use the whitespace character class \s instead of trim() like this:
const output = value.replace(/[_()-\s]/g, "");

Regex that allows a pattern to start with a an optional, specific character, but no other character

How can I write a regex that allows a pattern to start with a specific character, but that character is optional?
For example, I would like to match all instances of the word "hello" where "hello" is either at the very start of the line or preceded by an "!", in which case it does not have to be at the start of the line. So the first three options here should match, but not the last:
hello
!hello
some other text !hello more text
ahello
I'm specfically interested in JavaScript.
Match it with: /^hello|!hello/g
The ^ will only grab the word "hello" if it's at the beginning of a line.
The | works as an OR.
var str = "hello\n!hello\n\nsome other text !hello more text\nahello";
var regex = /^hello|!hello/g;
console.log( str.match(regex) );
Edit:
If you're trying to match the whole line beginning with "hello" or containing "!hello" as suggested in the comment below, then use the following regex:
/^.*(^hello|!hello).*$/gm
var str = "hello\n!hello\n\nsome other text !hello more text\nahello";
var regex = /^.*(^hello|!hello).*$/gm;
console.log(str.match(regex));
Final solution (hopefully)
Looks like, catching the groups is only available in ECMAScript 2020. Link 1, Link 2.
As a workaround I've found the following solution:
const str = `hello
!hello
some other text !hello more text
ahello
this is a test hello !hello
JvdV is saying hello
helloing or helloed =).`;
function collectGroups(regExp, str) {
const groups = [];
str.replace(regExp, (fullMatch, group1, group2) => {
groups.push(group1 || group2);
});
return groups;
}
const regex = /^(hello)|(?:!)(hello\b)/g;
const groups = collectGroups(regex, str)
console.log(groups)
/(?=!)?(\bhello\b)/g should do it. Playground.
Example:
const regexp = /(?=!)?(\bhello\b)/g;
const str = `
hello
!hello
some other text !hello more text
ahello
`;
const found = str.match(regexp)
console.log(found)
Explanation:
(?=!)?
(?=!) positive lookahead for !
? ! is optional
(\bhello\b): capturing group
\b word boundary ensures that hello is not preceded or succeeded by a character
Note: If you also make sure, that hello should not be succeeded by !, then you could simply add a negative lookahead like so /(?=!)?(\bhello\b)(?!!)/g.
Update
Thanks to the hint of #JvdV in the comment, I've adapted the regex now, which should meet your requirements:
/(^hello\b)|(?:!)(hello\b)/gm
Playground: https://regex101.com/r/CXXPHK/4 (The explanation can be found on the page as well).
Update 2:
Looks like the non-capturing group (?:!) doesn't work well in JavaScript, i.e. I get a matching result like ["hello", "!hello", "!hello", "!hello"], where ! is also included. But who cares, here is a workaround:
const regex = /(^hello\b)|(?:!)(hello\b)/gm;
const found = (str.match(regex) || []).map(m => m.replace(/^!/, ''));

How can I transfer every line which starts with specific patterns to the end of the string?

I have a string like this:
var str = " this is a [link][1]
[1]: http://example.com
and this is a [good website][2] in my opinion
[2]: http://goodwebsite.com
[3]: http://example.com/fsadf.jpg
[![this is a photo][3]][3]
and there is some text hare ..! ";
Now I want this:
var newstr = "this is a [link][1]
and this is a [good website][2] in my opinion
[![this is a photo][3]][3]
and there is some text hare ..!
[1]: http://example.com
[2]: http://goodwebsite.com
[3]: http://example.com/fsadf.jpg"
How can I do that?
In reality, that variable str is the value of a textarea ... and I'm trying to create a markdown editor .. So what I want is exactly the same with what SO's textarea does.
Here is my try:
/^(\[[0-9]*]:.*$)/g to select [any digit]: in the first of line
And I think I should create a group for that using () and then replace it with \n\n $1
try this:
strLinksArray = str.match(/(\[\d+\]\:\s*[^\s\n]+)/g);
strWithoutLinks = str.replace(/(\[\d+\]\:\s*[^\s\n]+)/g, ''); //removed all links
Here you will get links as array and string without links then do whatever changes you want.
You can use
var re = /^(\[[0-9]*]:)\s*(.*)\r?\n?/gm; // Regex declaration
var str = 'this is a [link][1]\n[1]: http://example.com\nand this is a [good website][2] in my opinion\n[2]: http://goodwebsite.com\n[3]: http://example.com/fsadf.jpg\n[![this is a photo][3]][3]\nand there is some text hare ..!';
var links = []; // Array for the links
var result = str.replace(re, function (m, g1, g2) { // Removing the links
links.push(" " + g1 + " " + g2); // and saving inside callback
return ""; // Removal happens here
});
var to_add = links.join("\n"); // Join the links into a string
document.getElementById("tinput").value = result + "\n\n\n" + to_add; // Display
<textarea id="tinput"></textarea>
See regex demo at regex101.com.
Regex explanation:
^ - start of line (due to the /m modifier)
(\[[0-9]*]:) - Group 1 (referred to as g1 in the replace callback) matching...
\[ - opening square bracket
[0-9]* - zero or more digits
] - closing square bracket
: - a colon
\s* - zero or more whitespace
(.*) - Group 2 matching (g2) zero or more characters other than newline
\r?\n? - one or zero \r followed by one or zero \n
/gm - define global search and replace and ^ matches line start instead of string start

Categories

Resources