This question has been asked a few times before, here's an example. However, the question linked only asks about getting one string out of the result. The text I would like to parse has many different instances of the trailing and leading strings, and thus the code below does not work:
test.match("SomeString(.*)TrailingString");
As shown in this fiddle. I will show you the intended result below:
If I were to have a string composed of the following elements STARTINGTEXTText I wantENDINGTEXT Text I don't want STARTINGTEXTMore text I wantENDINGTEXT Text I don't want
I would like to have a function that I can pass in the arguments STARTINGTEXT and ENDINGTEXT and it would return an array with "Text I want" and "More text I want"
Thanks!
EDIT - This is a Pebble Application so JQuery isn't an option.
This similar thing has been done in Objective-C:
-(NSMutableArray*)stringsBetweenString:(NSString*)start andString:(NSString*)end
{
NSMutableArray* strings = [NSMutableArray arrayWithCapacity:0];
NSRange startRange = [self rangeOfString:start];
for( ;; )
{
if (startRange.location != NSNotFound)
{
NSRange targetRange;
targetRange.location = startRange.location + startRange.length;
targetRange.length = [self length] - targetRange.location;
NSRange endRange = [self rangeOfString:end options:0 range:targetRange];
if (endRange.location != NSNotFound)
{
targetRange.length = endRange.location - targetRange.location;
[strings addObject:[self substringWithRange:targetRange]];
NSRange restOfString;
restOfString.location = endRange.location + endRange.length;
restOfString.length = [self length] - restOfString.location;
startRange = [self rangeOfString:start options:0 range:restOfString];
}
else
{
break;
}
}
else
{
break;
}
}
return strings;
}
If you would prefer a RegExp solution, you could do something like this:
var test = "STARTINGTEXTText I wantENDINGTEXT Text I don't want STARTINGTEXTMore text I wantENDINGTEXT Text I don't want";
var matches = test.match(/STARTINGTEXT(.*?)ENDINGTEXT/g);
The key to this is the "g" (or global) flag, and the non-greedy repeat operator "*?". See this link for an explanation of the "g" flag and the non-greedy operator.
Here is a modification of your fiddle: link. I changed it so that the alert would show a stringified JSON of the results, so that you could see it matching both strings.
This methodology uses very little code:
function getBetweenText(fromString, ignoreStart, ignoreEnd){
var s = fromString.split(new RegExp(ignoreStart+'|'+ignoreEnd)), r = [];
for(var i=1,l=s.length; i<l; i+=2){
r.push(s[i]);
}
return r;
}
console.log(getBetweenText("STARTINGTEXTText I wantENDINGTEXT Text I don't want STARTINGTEXTMore text I wantENDINGTEXT Text I don't want", 'STARTINGTEXT', 'ENDINGTEXT'));
You can do this using jQuery. To select all the elements with specific tag you just do something like this: ** UPDATED WITH NON-JQUERY VERSION **
var HTMLelements = document.getElementsByTagName("tag");
var results = [];
for(var i = 0; i < HTMLelements.length; i++){
results.push(HTMLelements[i].innerHTML);
}
Related
My goal is to edit the string (which has an email) to mask the first part, like say the email is johndoe#abc.com then I should output j*****e#abc.com.
var maskPII = function(S) {
var ans = "";
if(S.includes("#")){
S = S.toLowerCase();
var parts = S.split("#");
var first = parts[0];
for(var i=0;i<parts[0].length;i++){
if(i!=0 && i!=parts[0].length - 1)
first[i] = '*';
}
ans = first +"#" +parts[1];
}else{
}
return ans;
};
However in my loop I can't change the characters to asterisks.
After execution I see value of first still same as parts[0] and has no asterisks, can some one explain why? Also, what would I need to do to modify the variable inside loop?
To answer your question... javascript allows you access values of a string using [] indexing.. but that is read only access... you cannot insert/replace values using that operator.
Ref: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String
When using bracket notation for character access,
attempting to delete or assign a value to these properties will not succeed.
The properties involved are neither writable nor configurable.
(See Object.defineProperty() for more information.)
You need to extract the values you want to keep from the existing string and build up a new string as noted in other answers...
Well, this's what you're looking for, and this will be the output j*****e#abc.com.
var ans = "";
var S = "johndoe#abc.com"; //example
S = S.toLowerCase();
var parts = S.split("#");
var first = "";
for(var i = 0; i < parts[0].length; i++){
if(i != 0 && i != parts[0].length - 1){
first += '*';
}else{
first += parts[0][i];
}
}
ans = first +"#"+ parts[1];
console.log(ans);
Here is the code with your approach:
var maskPII = function(S) {
var ans = "";
if(S.includes("#")){
S = S.toLowerCase();
var parts = S.split("#");
var first = parts[0][0];
for(var i=0;i<parts[0].length;i++){
if(i!=0 && i!=parts[0].length - 1)
first += '*';
}
ans = first + parts[0][parts[0].length - 1] +"#" +parts[1];
}else{
}
return ans;
};
But if i were you i would use:
var mail = "johndoe#abc.com";
mail = mail.replace(/(?<=.)(.+?)(?=.#)/gi, '*'.repeat(mail.split('#')[0].length - 2));
console.log(mail);
You can use the bracket notation on a string (like an array) to get the character at a specific index, but you can't use this to change characters. So first[i] = '*' in your code wont do anything.
Strings in JavaScript are immutable. This means that if you want to change a string, a new string instance will be created. This also means that when you change a string in a for-loop, it can impact performance. (Although in this case the difference wont be noticeable.
)
I would use this code:
function maskPII(str) {
const indexOfAt = str.indexOf('#');
if (indexOfAt <= 2) {
return str;
}
return str[0] + '*'.repeat(indexOfAt - 2) + str.substring(indexOfAt - 1);
}
const email = 'johndoe#abc.com';
console.log(email);
console.log(maskPII(email));
It will look for the index of the # sign. If the index is less or equal than 2, (when not found the index will be -1) it will return the original string.
Otherwise it will get the first character, calculate the amount of asterisks needed (index of the # sign -2) and repeat those and then add the rest of the original string.
As a mean to explain I am not posting the gigantic string I have (which contains dynamic html tags and are auto-generated with unique id). I want to get the text between every tag that says "<p class=partial_entry>... comment...</p>" using anything excep Regex, and in my case ill have a string of 20 repeated tags by getting the outerHTML. I have an example below:
var str = "<div class=prw_rup prw_reviews_text_summary_hsx data-prwidget-name=reviews_text_summary_hsx data-prwidget-init=handlers>
<div class=entry><p class=partial_entry>You have to try their special sushi rolls like acevichado or patrullero. They have great selections of sushi and other dishes.</p>
</div></div><div class=prw_rup prw_reviews_text_summary_hsx data-prwidget-name=reviews_text_summary_hsx data-prwidget-init=handlers><div class=entry><p class=partial_entry>
All you can eat sushi fir $20 ($24 including tax)! Christian, our server, was wonderful and attentive.
</p></div></div><div class=prw_rup prw_reviews_text_summary_hsx data-prwidget-name=reviews_text_summary_hsx data-prwidget-init=handlers>
<div class=entry><p class=partial_entry>The place was good, also the waiters, but definitely sushi is the best in town
for my opinion, even with the few options of it in this place. I will be there soon again.</p></div></div>";
What I want is the 3 comments I have in my example so I use the code for 20:
- You have to try their special sushi rolls like acevichado or patrullero. They have great selections of sushi and other dishes.
- All you can eat sushi fir $20 ($24 including tax)! Christian, our server, was wonderful and attentive.
- The place was good, also the waiters, but definitely sushi is the best in town for my opinion, even with the few options of it in this place. I will be there soon again.
I tried making my own code but the text or tags in between are not taken off since it detects the tag I preset, example: "THE WHOLE STRING AFTER THE TAG IM LOOKING FOR + <p class=partial_entry>... comment...</p>" and I only want ...comment... part.
The code I made is below:
var temp = "<p class=partial_entry";
var res = str.split('>');
var res2 = res.indexOf(temp) + 1;
var resultado = null;
if (res2 < res.length && res2 != -1) {
resultado = res[ res2 ]; // gets the next one
}
alert(resultado);
This is pretty trivial, assuming the comments will always be wrapped in a node with class partial_entry:
var commentNodes = document.getElementsByClassName('partial_entry');
var comments = [];
for (var i = 0; i < commentNodes.length; i++) {
comments.push(commentNodes[i].innerText);
}
You could use a for loop that loops through every single character until it sees , then stores every character until it sees
It probably isn't the best way, and won't work if there's other tags inside the p. But it works.
var text = "<p class=partial_entry>This text should show up</p>"
var seenBeginTag = false;
var seenEndTag = false;
var output = [];
for (var i = 0; i < text.length; i++)
{
if (seenBeginTag && seenEndTag) {
if (text[i] == '<')
{
seenBeginTag = false;
seenEndTag = false;
}
else {
output.push(text[i]);
}
}
else if (seenBeginTag) {
if (text[i] == '>')
{
seenEndTag = true;
}
}
else if (text[i] == '<') {
if (text[i+1] == 'p') {
seenBeginTag = true;
}
}
}
console.log(output.join(''));
I want to replace multiple words on a website with other words. That is, I am interested in finding all instances of a source word and replacing it with a target word.
Sample Cases:
Source | Target
Molehill => Mountain
Green => Grey
Google => <a href="http://google.com">
Sascha => Monika
Football => Soccer
This is somewhat of a half answer. It shows the basic process, but also illustrates some of the inherent difficulties in a process like this. Detecting capitalization and properly formatting the replacements would be a bit intensive (probably utilizing something like this on a case-by-case basis How can I test if a letter in a string is uppercase or lowercase using JavaScript?). Also, when dealing with text nodes, innerHTML isn't an option, so the google replacement comes out as plain text instead of HTML.
TLDR - If you have another way to do this that doesn't involve javascript, do it that way.
var body = document.querySelector('body')
function textNodesUnder(el){
var n, a=[], walk=document.createTreeWalker(el,NodeFilter.SHOW_TEXT,null,false);
while(n=walk.nextNode()) a.push(n);
return a;
}
function doReplacements(txt){
txt = txt.replace(/sascha/gi, 'monika')
txt = txt.replace(/mountain/gi, 'molehill')
txt = txt.replace(/football/gi, 'soccer')
txt = txt.replace(/google/gi, 'google')
console.log(txt)
return txt
}
var textnodes = textNodesUnder(body),
len = textnodes.length,
i = -1, node
console.log(textnodes)
while(++i < len){
node = textnodes[i]
node.textContent = doReplacements(node.textContent)
}
<div>Mountains of Sascha</div>
<h1>Playing football, google it.</h1>
<p>Sascha Mountain football google</p>
Here is the JS:
function replaceWords () {
var toReplace = [
["Green","Grey"],
["Google","<a href='http://google.com'>"]
];
var input = document.getElementById("content").innerHTML;
console.log("Input: " + input);
for (var i = 0; i < toReplace.length; i++) {
var reg = new RegExp(toReplace[i][0],"g");
input = input.replace(reg,toReplace[i][1]);
}
document.getElementById("content").innerHTML = input;
};
replaceWords();
So I'm working on this project that involves translating a string of text such as "als;kdfja;lsjkdf" into regular charaters like "the big dog" by parsing for certain pairs of letters that translate. (i.e: "fj" = "D")
The catch is I cant simply use the .replace() function in javascript, because there are many occurences where it's given the text "fjkl", and needs to find "jk" and logically interprets the collision of "fj" and "kl" to say that it's found it. This wont work for me, because for me, it didnt find it, as i am only trying to look at found pairs within 2 characters at a time. (i.e: "fjkl" could only yeild "fj" and "kl".)
(In the end I intend to utilize just the 8 characters "asdfjkl;" and set pairs of characters to actual letters. (in this subsitution method, fyi, "fj" OR "jf" would actually be "_"(space). )
in trying to figure out this task in javascript, (I dont know if another language might handle it more efficiently,) I tried utilizing the "split" function in the following way. (Disclaimer, I'm not sure if this is formatted 100% perfectly)
<textarea id="textbox"></textarea>
<script>
var text = document.getElementById("textbox").value; //getting string from the textarea
var pairs = text.split(/(..)/).filter(String); //spliting string into pairs
if(pairs == "fj"){replace(pairs, " ")} //some sort of subsitution
</script>
Additionally, if possible, i would like the replaced characters to be fed directly into the textarea continuosly as the user types, so the translation happens almost simutaneously. (I'm assuming this will use some sort of setInterval() function?)
If any tips can be given on the correct formatting of which tools i should use in javascript, that would be very outstanding; Thanks in advance.
if your interested, here is full list of subsitutions im making in the end of this project:
syntax:(X OR Y == result)
AJ JA = F
AK KA = V
AL LA = B
A; ;A = Y
SJ JS = N
SK KS = M
SL LS = S
S; ;S = P
DJ JD = A
DK DK = U
DL LD = D
D; ;D = G
FJ JF = _
FK KF = I
FL LF = T
F; ;F = K
AS SA = C
SD DS = L
DF FD = E
JK KJ = O
KL LK = R
L; ;L = Z
AD DA = -
SF FS = ,
AF FA = .
JL LJ = !
K; ;K = :
J; ;J = ?
-Daniel Rehman
I have prepared a code for your requirement. You can bind a function on keydown to allow continuous changes as you type in the textarea.
I am using replacePair method to replace a pair of character by its equivalent uppercase representation. You can inject your own custom logic here.
var tb = document.getElementById('tb');
var processedLength = 0;
var pairEntered=false;
tb.onkeydown = function (e) {
pairEntered=!pairEntered;
if (pairEntered) {
var nextTwoChars = this.value.substr(this.value.length - 2, 2);
var prevPart=this.value.substr(0,this.value.length-2);
var finalText=prevPart+ replacePair(nextTwoChars);
this.value=finalText;
processedLength+=2;
}
}
function replacePair(str){
return str.toUpperCase();
}
jsfiddle:http://jsfiddle.net/218fq7t2/
updated fiddle as per your replacement logic: http://jsfiddle.net/218fq7t2/3/
If you can be assured that certain pairs always translate to the same character, then perhaps a dictionary object can help.
var dict = { as:"A", kl:"B", al:"C", fj:"D" ... };
And, if your 'decryption' algorithm is 'lazy' (evaluates the first pair it encounters), then you can just travel through the input string.
var outputString = "", c, cl;
for (c = 1, cl = inputString.length; c < cl; c += 2) {
outputString += dict[inputString[c-1] + inputString[c]] || "";
}
If your replacement algorithm is not any more complicated than simply looking up which letter the pair represents, then this should do alright for you. No real logic necessary.
Couldn't you do it as follows:
var text = document.getElementById("textbox").value;
for (i = 0; i <= text.length; i++) {
if (text[i] == "j") {
if (text[i+1] == "f") {
pair = "jf";
text = text.replace(pair, "_");
}
}
What this would do is it would always, when checking any letter, also check the letter after it during the same step in the procedure. When it finds both letter i and letter i+1 matching up with a pair you are looking for, then the letters will be replaced by a space (or whatever you want), meaning that when the for-loop reaches the next run after a pair was found, the size of the text string will have been reduced by one. Thus, when it increments i, it will automatically skip the letter that made up the second component of the found pair. Thus, "jfkl" will be identified as two different pairs and your algorithm will not be confused.
of course, you would also have to work in the other pairs/codewords into the for loop so that they are all checked in some way
I had hoped my previous answer was enough to get you started. I was merely providing an algorithm that you could then use to your liking (wrap it in a function and add your own event listeners, etc).
Here is the solution to your problem. I did not write the entire dictionary. You will need to complete that.
var dictionary = { "aj":"F", "ja":"F", "ak":"V", "ka":"V", "al":"B", "la":"B", "a;":"Y", ";a":"Y" }
var input, output;
function init() {
input = document.getElementById("input");
output = document.getElementById("output");
input.addEventListener("keyup", decrypt, false);
}
function decrypt () {
if (!input || !output) {
return;
}
var i = input.value, o = "", c, cl;
for (c = 1, cl = i.length; c < cl; c += 2) {
o += dictionary[ i[c-1] + i[c] ] || "";
}
while (output.hasChildNodes()) {
output.removeChild(output.firstChild);
}
output.appendChild(document.createTextNode(o));
}
window.addEventListener("load", init, false);
<textarea id="input"></textarea>
<div id="output"></div>
I'm sort of creating typing tutor with custom options.
Not a professional (don't get mad at me for being wrong-person-wrong place) but thanks to helpful forums like stackoverflow.com and contributing traffic/people I'm able to pull it out in a day or two.
Directly now, here!
while (i < len+1){
if(boxarray[i] == orgarray[i]){
++i;
actualScore = i - 1;
}
I've searched already, '==' operator is of no use, I will not go for JSON.encode. I met similar solution at this page . But in my case I've to loop through each word while comparing two sentences. Detail is trivial, if someone please help me solve above, I won't return with complain on the same project, promise.
Okay I'm putting more code if it can help you help me.
var paratext = document.getElementById('typethis').innerHTML;
var orgstr = "start typing, in : BtXr the yellow box but. please don't shit." ;
var boxtext = document.getElementById('usit').value;
var endtrim = boxtext;
var actualScore;
var orgarray = listToArray(orgstr," ");
var boxarray = listToArray(boxtext," ");
var len = boxarray.length;
var i = 0;
var actualScore; //note var undefined that's one mistake I was making [edit]
if(orgstr.indexOf(boxtext) !== -1){
while (i < len+1){
if(boxarray[i] == orgarray[i]){
++i;
actualScore = i - 1;
}
}
alert(actualScore);
}
If I follow what you're after how about something like this:
http://jsfiddle.net/w6R9U/
var s1 = 'The dog sleeps';
var s2 = 'the dog jogs';
var s1Parts= s1.split(' ');
var s2Parts= s2.split(' ');
var score = 0;
for(var i = 0; i<s1Parts.length; i++)
{
if(s1Parts[i] === s2Parts[i])
score++;
}
"The dog sleeps" and "the dog sleeps" results in a score of 2 because of case (which could be ignored, if needed). The example above results in a score of 1. Could get a percent by using the length of the sentences. Hope this helps! If nothing else might get you started.
The following will compare each individual character, decreasing the "actualScore" for each inequality:
http://jsfiddle.net/ckKDR/
var sentence1 = "This is the original sentence.", // original text
sentence2 = "This is teh originel sentence.", // what the user typed
length = sentence1.length,
actualScore = length, // start with full points
i = 0;
while(i<length){
if(sentence1[i]!==sentence2[i]){
actualScore--; // subtract 1 from actual score
}
i++; // move to the next index
}
alert("'sentence2' is "+Math.round(100*(actualScore/length))+"% accurate");
Let's say the input is your two sentences as strings.
Then the first thing to do is to create two temporary strings, with all the non-word characters eliminated (e.g. punctuation characters). Split the sentences into string arrays by word delimiters.
Then you can assign an integer variable to score. Create an outer loop and an inner loop for the two sentences. When the words match in the sentences, increment the variable by 1, remove the word from the 2nd sentence (replace the word with a non-word character) and break out of the inner loop.
Also, use this operator for word comparison instead:
===
Your problem is
if (boxarray[i] = orgarray[i])
The single = is the assignment operator. Replace it with
===
to be a comparison.
You are not comparing you are assigning
if(boxarray[i] = orgarray[i]){
^^^
So it will be true on each iteration. Fix the typo to actually perform the check you want
if(boxarray[i] === orgarray[i]){
^^^
And how you are calculating the score looks to be wrong. You should be doing something like
var score = orgstr.length;
while...
if(boxarray[i] === orgarray[i]){
score--;
}
{
string1="string1";
string2="string2 is here";
changepercent(string1,string2);
}
function changepercent(string1,string2) {
var s1Parts= string1.split(' ');
var s2Parts= string2.split(' ');
var matched = 0;
for(var i = 0; i<s1Parts.length; i++)
{
for(var j = 0; j<s2Parts.length; j++)
{
if(s1Parts[i] === s2Parts[j])
matched++;
}
}
var percentage=(matched/Math.max(s1Parts.length, s2Parts.length))*100;
console.log(matched);
console.log(percentage);
if(percentage<50)
{
console.log("Change Above 50%");
}
}
Slightly modified first code