dicordjs string manipulation - javascript

if(msg.content.includes("[mid]")) {
let str = msg.content
let pokeID = str.substring(
str.indexOf("[mid]") + 5,
str.lastIndexOf("[/mid") //get the unique-code for a pokemon
);
msg.channel.send({ content: `Here is your Pokemon:`, embeds: [midData(pokeID)] });
this code works fine, I'm would to be able to put in any user text that is before or after the [mid]code[/mid]
example user inputs "this text can be of any length or even null [mid]unique-code[/mid] this text can also be of any text or null"
the output should be :
this text can be of any length or even null this text can also be of any text or null
[mid]unique-code[/mid] (which is a link)
I have tried this: https://imgur.com/a/uq8CVpn //image of output
I need 3 strings from the user input.
string1 = all text, if any before [mid]unique-code[/mid] // pokemon code
string2 = [mid]unique-code[/mid]
string3 = all text if any behind [mid]unique-code[/mid] //pokemon code
using node v16 and discord v13
thank you

You just need to use lastIndexOf and substring like this (I also assumed you meant after and not behind in string3) :
also for clarification substring works like this:
substring(startIndex, endIndex /*defaults to the end of the string if not specified*/ )
const message = "this text can be of any length or even null [mid]unique-code[/mid] this text can also be of any text or null"
const beforeCode = message.substring(0, message.lastIndexOf("[mid]")).trim()
const afterCode = message.substring(message.lastIndexOf("[/mid]") + 6).trim()
const code = message.substring(
message.lastIndexOf("[mid]") + 5,
message.lastIndexOf("[/mid]")
).trim();
console.log("beforeCode:", beforeCode, "\nafterCode:", afterCode, "\ncode:", code)
to get the text before the unique code we substring the message from index 0 (the message's start) -> start index of "[mid]"
to get the text after the unique code we substring the message from end index of "[mid/]" -> end of the string
to get the unique code we substring the message from end index of "[mid]" -> start index of [mid/]
I also use trim to remove any spaces from the start or end of the string

Related

Regex to get parts of a string

all i am struggling to get sections of a string with regex without using Split or any other similar function here is my scenario:
I have this text U:BCCNT.3;GOwhich i want to get the different sections divided but the symbols in the middle I have managed to get the first one with this regex /(.+):/.exec(value) this gives me the first word till the colon(:) and these are the different variations of the value
Second section BCCNT
BCCNT.3;GO -> without the U: so the string might also contain no colon so for the second section the logic would be any text that is between : and . or any text ending with . and nothing infront
Third section .3-> any text starting with a . and ending with nothing or anytext staring with a . and ending with a ; semicolon
Fourth section ;GO-> any text starting with a ; and ending with nothing
EDIT
and preferably on separate variables like
const sectionOne = regex.exec(value);
const sectionTwo = regex.exec(value);
const sectionThree = regex.exec(value);
const sectionFour = regex.exec(value);
and which ever value doesnt match the pattern the variable would just be undefined or null or any empty string
Here is a regex approach using 4 separate optional capture groups for each possible component:
var input = "U:BCCNT.3;GO";
var re = /^([^:]+:)?([^.]+)?(\.[^;]+)?(;.*)?$/g;
var m;
m = re.exec(input);
if (m) {
console.log(m[1], m[2], m[3], m[4]);
}
Something like
/^(?:([^:]*):)?([^.]*)\.(?:([^;]*);(.*))?/
For example:
const s = 'U:BCCNT.3;GO';
const m = s.match(/^(?:([^:]*):)?([^.]*)\.(?:([^;]*);(.*))?/);
console.log(m);

Replace first occurrence with one value and second with another

Giving this original string...
Test text _with bold_ and perhaps one another text _with bold in the same string_.
... how to efficiently replace the first occurrence of " _ " with "< b >" and the second occurrence " _ " with "< /b >" to achieve the following result:
Test text <b>with bold</b> and perhaps one more text <b>with bold in the same string</b>.
Note: I have an array of hundreds of those strings that will need to go through this process in order to render in the page.
You can use regex for this.
The replace-pattern is the following:
_(.*?)_ with the flag g at the end - so it will replace until all occurances are satisfied.
The ? in the regex says it will stop matching at the first _ afert the opening _ (non-greedy).
<b>$1</b> says replace the matched string with this. Where the $1 refers to the content matched in the brackets ()
var text = "This is _bold text_ and here _some more_";
var text_replaced = text.replace(/_(.*?)_/g, '<b>$1</b>');
document.getElementById('result').innerHTML = text_replaced;
<span id="result" />
You can run a while loop which checks if there any more underscores in the text and replaces them, assuming that there must be an even number of "_" in the text:
var test = "text _with bold_ and perhaps one another text _with bold in the same string_.";
b_index = test.indexOf("_");
while (b_index != -1) {
test = test.replace("_", "<b>");
test = test.replace("_", "</b>");
b_index = test.indexOf("_");
}
After the while loop, you can assign the innerHTML of whichever element you wish to the variable test.

How to extract a pattern and embed it into span elements using javascript?

i am new to programming. i want to extract a string and embed it into span element how can i do it?
consider i have string
"i am [12#some user] some text [2#some user2]"
i want to identity strings in square brackets and extract the values after # so
"some user" and "some user2" should be extracted and form a string like below,
"i am <span>some user</span> some text <span>some user2</span>"
how do i do it using the algorithm below
const final_string = []
const original_string = "i am [12#some user] some text [2#some user2]"
let prev_match_pos = 0
for each match in original_string
final_string.push(text from the end of prev match up until current
match start)
final_string.push(<span>match</span>)
update prev_match_pos
final_string.push(text from the end of previous match to the end of the
original string)
i am using this pattern to match /[\d+#(?[^]\r\n]*)]/g
const matches = original_string.matchAll(/\[\d+#(?<name>[^\]\r\n]*)]/g);
let matches_another = [];
for (const match of matches) {
matches_another.push(match.groups.name);
}
Now how do i get to do the other part of the algorithm. i get the matches in matches_another array.
now how to proceed further. could someone help me with this thanks.
You can extract the two words like:
let str = "i am [12#some user] some text [2#some user2]";
let reg = /\[\w*#/;
let user1 = str.split(reg)[1].split(']')[0];
let user2 = str.split(reg)[2].slice(0,-1);
console.log('user1= ' + user1 +' & user2= '+ user2);
If you don't need to keep the matches, String.replace with a regex will work:
const original_string = "i am [12#some user] some text [2#some user2]";
const final_string = original_string.replace(/\[\d+#([^\]\r\n]*)]/g, '<span>$1</span>');
console.log(final_string);
(I've removed the named group from the regex because it's not supported everywhere and it's not necessary here.)

Apply array of string with string.replace

Let's say I have a string like so:
const sentence = "This is my custom string";
I want to highlight the words of a input field inside this sentence.
Let's say a say user typed a string and I have converted the separate words into an array like so:
["custom", "string", "is"]
I know want to replace the words in my sentence with a highlighted version of the words in my array. For a single word I would do something like this:
const word = 'custom';
const searchFor = new RegExp(`(${word})`, 'gi');
const replaceWith = '<strong class="highlight">$1</strong>';
const highlightedSentence = sentence.replace(searchFor, replaceWith);
How can I apply this logic with an array to the entire sentence?
I can't simply loop through it because the string will contain my highlighted class which will also be taken into the highlighting process the the second loop, third loop, etc.
This means that on a second loop if a user where to type:
"high custom"
I would highlight my highlighted class, leading to highlight inception.
For an example of what I mean try commenting/uncommenting the 2 highlighter functions:
https://jsfiddle.net/qh9ttvp2/1/
Your problem is that while replacing words, you replace already added html tag with .class 'highlight'.
Solution here could be to replace anything that is not html tag. Replace this line in you jsfiddle example.
const searchFor = new RegExp(`(${word})(?!([^<]+)?>)`, 'gi');
You can split you sentence into array and check if your element is already highlighted:
let sentence = "This is a some type of long string with all kinds of words in it, all kinds.";
let sentenceArr = sentence.split(' '); // make an array
const query = "kinds words all type";
function highlighter(query, sentence) {
const words = query.match(/\S+/g);
words.forEach((word) => {
// Create a capture group since we are searching case insensitive.
const searchFor = new RegExp(`(${word})`, 'gi');
const replaceWith = '<strong class="highlight">$1</strong>';
sentenceArr = sentenceArr.map(sw => (sw.indexOf('strong class="highlight"') === -1) ? sw.replace(searchFor, replaceWith) : sw); // if already highlited - skip
//sentence = sentence.replace(searchFor, replaceWith);
});
// console.log(sentence);
document.querySelector('.highlighted-sentence').innerHTML = sentenceArr.join(' '); // notice sentenceArr
}
// Works.
//highlighter('kinds words all type', sentence);
// Doesn't work.
highlighter('kinds words high', sentence);
<div class="highlighted-sentence"></div>

How to detect line breaks in a text area input?

What is the best way to check the text area value for line breaks and then calculate the number of occurrences, if any?
I have a text area on a form on my webpage. I am using JavaScript to grab the value of the text area and then checking its length.
Example
enteredText = textareaVariableName.val();
characterCount = enteredText.length; // One line break entered returns 1
If a user enters a line break in the text area my calculation above gives the line break a length of 1. However I need to give line breaks a length of 2. Therefore I need to check for line breaks and the number of occurrences and then add this onto the total length.
Example of what I want to achieve
enteredText = textareaVariableName.val();
characterCount = enteredText.length + numberOfLineBreaks;
My solution before asking this question was the following:
enteredText = textareaVariableName.val();
enteredTextEncoded = escape(enteredText);
linebreaks = enteredTextEncoded.match(/%0A/g);
(linebreaks != null) ? numberOfLineBreaks = linebreaks.length : numberOfLineBreaks = 0;
I could see that encoding the text and checking for %0A was a bit long-winded, so I was after some better solutions. Thank you for all the suggestions.
You can use match on the string containing the line breaks, and the number of elements in that array should correspond to the number of line breaks.
enteredText = textareaVariableName.val();
numberOfLineBreaks = (enteredText.match(/\n/g)||[]).length;
characterCount = enteredText.length + numberOfLineBreaks;
/\n/g is a regular expression meaning 'look for the character \n (line break), and do it globally (across the whole string).
The ||[] part is just in case there are no line breaks. Match will return null, so we test the length of an empty array instead to avoid errors.
Here's one way:
var count = text.length + text.replace(/[^\n]/g, '').length;
Alternatively, you could replace all the "naked" \n characters with \r\n and then use the overall length.
I'd do this using a regular expression:
var inTxt = document.getElementById('txtAreaId').value;
var charCount = inTxt.length + inTxt.match(/\n/gm).length;
where /\n/ matches linebreaks (obviously), g is the global flag. m stands for mult-line, which you evidently need in this case...Alternatively, though as I recall this is a tad slower:
var charCount = inTxt.length + (inTxt.split("\n").length);
Edit
Just realized that, if no line breaks are matched, this will spit an error, so best do:
charCount = intTxt.length + (inTxt.match(/\n/) !== null ? inTxt.match(/\n/gm).length : 0);
Or something similar...
For new JS use encodeURI(), because escape() is deprecated in ECMAScript 1.5.
Instead use:
enteredText = textareaVariableName.val();
enteredTextEncoded = encodeURI(enteredText);
linebreaks = enteredTextEncoded.match(/%0A/g);
(linebreaks != null) ? numberOfLineBreaks = linebreaks.length : numberOfLineBreaks = 0;
You can split the text based on new lines:
let textArray = text.split(/^/gm)
console.log(textArray.length)

Categories

Resources