0

I have the following sentence with quiz items to solve.

With regex I can easily identify these items and replace them with a text, e.g. to get a quiz sentence.

However, can replace the items with an array of strings, e.g. so that I can build the correct sentence by replacing each item with its appropriate answer?

const regex = /(\[.*?\])/gm;
const text = 'This [is/are] a sentence, and those [is/are] some apples.';
const answers = ['is', 'are'];

const replaceAllRegex = (text, regex, replace) => text.replace(new RegExp(regex, 'g'), replace);

const phrases = {};
phrases.cloze = replaceAllRegex(text, regex, '[_________]');
for (const answer of answers) {
    phrases.right = replaceAllRegex(text, regex, answer);
}

console.log(phrases.cloze); 
// OUTPUTS: This [_________] a sentence, and those [_________] some apples.

console.log(phrases.right) 
// OUTPUTS: This are a sentence, and those are some apples.
// SHOULD OUTPUT: This is a sentence, and those are some apples.
4
  • You're overwriteing phrases.right every time through the loop. The first time will use is, the second time will use are. Commented May 27, 2021 at 20:30
  • 2
    How is the code supposed to know which ons is really correct? Commented May 27, 2021 at 20:30
  • Do not use g (global). Then you can iterate and replace individually. Commented May 27, 2021 at 20:31
  • Yeah, I just coded it the best I could and that is exactly the problem: I can't find any hook to say that I want the first element of the answers array to replace the first match, and the second element in the answers array to replace the second match, etc. Commented May 27, 2021 at 20:32

2 Answers 2

2

I think that you are considering the correct answers by the order they appear in the answers array. So an option would be, for each element of answers, replace the next regex's match with it.

Something like:

const regex = /(\[.*?\])/;
const text = 'This [is/are] a sentence, and those [is/are] some apples.';
const answers = ['is', 'are'];

let final = text;
for (const answer of answers) {
  final = final.replace(regex, answer);
}

console.log(final); // This is a sentence, and those are some apples.

Or you can use the replacer function which String.prototype.replaceAll accepts, with an incrementing counter:

const regex = /(\[.*?\])/g;
const text = 'This [is/are] a sentence, and those [is/are] some apples.';
const answers = ['is', 'are'];

let curr = 0;
final = text.replaceAll(regex, () => {
  return answers[curr++];
});

console.log(final);


Note: In both of the previous excerpts of code, you may also want to check if the number of matches is equal to the number of elements in the answers array. I've omitted this kind of verification to keep the code small and just give the idea.

Sign up to request clarification or add additional context in comments.

Comments

1

This answer allows you to keep your replaceAllRegex function for both question setup and answer.

The global flag was preventing your script from identifying individual replacements on the second for loop. I made that an argument of your function, and also, passed the modified phrases.right through your iterator rather than text, so it would replace each item in sequence one at a time.

const regex = /(\[.*?\])/gm;
const text = 'This [is/are] a sentence, and those [is/are] some apples.';
const answers = ['is', 'are'];

const replaceAllRegex = (text, regex, replace, global) => text.replace(new RegExp(regex, global || ''), replace);

const phrases = {};
phrases.cloze = replaceAllRegex(text, regex, '[_________]', 'g');

phrases.right = text;

for (const answer of answers) {
  phrases.right = replaceAllRegex(phrases.right, regex, answer);
}

console.log(phrases.cloze);
// OUTPUTS: This [_________] a sentence, and those [_________] some apples.

console.log(phrases.right)
// OUTPUTS: This are a sentence, and those are some apples.
// SHOULD OUTPUT: This is a sentence, and those are some apples.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.