Home > Enterprise >  How to randomly pick and replace a value from a template-string's options-pattern?
How to randomly pick and replace a value from a template-string's options-pattern?

Time:10-06

Aim:extract sentences or paragraphs from the given syntax structure. Pick any random word/phrase between “{” & “}” separated by “|” and make one realistic output.

Input:

{Hi|Hello|Hola} @name, Good {Morning|Evening}. {I am|We are} very {glad|hapy) that you came here {to meet us.

Output1: Hi abc Good Morning, I am very glad that you came here to meet us.

Output2: Hola abc Good Evening, I am very happy that you came here to meet us.

Output3: Hello abc Good Morning, We are very glad that you came here to meet us.

function extract([beg, end]) {
  const matcher = new RegExp(`${beg}(.*?)${end}`,'gm');
  const normalise = (str) => str.slice(beg.length,end.length*-1);
  return function(str) {
      return str.match(matcher).map(normalise);
  }
}
var str = "{Hi|Hello|Hola} @name, Good {Morning|Evening}. {I am|We are} very {glad|hapy) that you came here {to meet us."
const stringExtractor = extract(['{','}']);
const stuffIneed = stringExtractor(str)

I have extract the words between {} in array and now trying to compare and replace them

CodePudding user response:

One would go for String.prototype.replace with a regex and a related replacement function where one implements the access of the provided template string's text alternatives as e.g. options.

I personally would choose a regex which captures the options related data directly. Something like ... /\{([^}] )\}/g ... or same with a named capturing group ... /\{(?<options>[^}] )\}/g.

  • The regex is going to match

    • \{ ... a single opening brace ... followed by ...
    • ([^}] ) ... at least one character which is not a closing brace ... followed by ...
    • \} ... a single closing brace.
  • Since the character sequence of the second point is enclosed by parenthesis ( ... ) it will be captured/remembered. One also could go for a named capturing group where one just needs to declare the group name ... (?<options> ... )

The related replacement function will get passed every regex result as parameters of following form [match, options, offset, string, groups] where options is the sole captured group and match is the entire matching string. In our case everything except options can be ignored.

  • options needs to be split at every pipe character ...
  • ... which then gives the opportunity to randomly pick a string from the just split array.
  • This string is both the replacement function's return value and thus the value which replaces the regular expressions entire match.

const sampleTemplate =
  `{Hi|Hello|Hola} @name, Good {Morning|Evening}. {I am|We are} very {glad|hapy} that you came here to meet us.`;

// see ... [https://regex101.com/r/zXJS1s/2]
const regXReplacementOptions = /\{([^}] )\}/g;

function pickRandomOption(match, options) {
  options = options.split('|');
  return options[Math.floor(Math.random() * options.length)];
}
console.log([

  sampleTemplate
    .replace(regXReplacementOptions, pickRandomOption),

  sampleTemplate
    .replace(regXReplacementOptions, pickRandomOption),

  sampleTemplate
    .replace(regXReplacementOptions, pickRandomOption),

].join('\n'));
.as-console-wrapper { min-height: 100%!important; top: 0; }

CodePudding user response:

One solution is by using regular expressions Here is a code snippet

I isolated the {...} parts, then split them by |, used random and then replaced the original {...} part with the random element

let t = '{Hi|Hello|Hola} @name, Good {Morning|Evening}. {I am|We are} very {glad|hapy} that you came here to meet us.'
let matches = t.match(/{([A-Z ](\|*))*}/gi)

for (const match of matches) {
  let splt = match.replace('{', '').replace('}', '').split('|')
  t = t.replace(match, splt[Math.floor(Math.random() * splt.length)])
}

console.log(t)

Second approach using a method

let t = '{Hi|Hello|Hola} @name, Good {Morning|Evening}. {I am|We are} very {glad|hapy} that you came here to meet us.'

function printSentence(sentence) {
 let matches = t.match(/{([A-Z ](\|*))*}/gi)

  for (const match of matches) {
    let splt = match.replace('{', '').replace('}', '').split('|')
    sentence = sentence.replace(match, splt[Math.floor(Math.random() * splt.length)])
  }

  console.log(sentence)
}


printSentence(t)
printSentence(t)
printSentence(t)

CodePudding user response:

One way to achieve this is, to keep all possible values in an array and generate a complete string by picking items randomly

    const salutation = ['Hi', 'Hello','Hola']
    const timeOfDay = ['Morning', 'Evening']
    const feeling = ['glad', 'happy']
    const refer = ['I am', 'We are']

    const phrase = `${salutation[(Math.random() * salutation.length) | 0]} @name, Good ${timeOfDay[(Math.random() * timeOfDay.length) | 0]}. ${refer[(Math.random() * refer.length) | 0]} very ${feeling[(Math.random() * feeling.length) | 0]} that you came here to meet us.`
    
    console.log(phrase)

  • Related