识别用户填写的空白。

huangapple go评论78阅读模式
英文:

Recognise the blanks a user has filled in

问题

I am writing a Javascript function to recognise the blanks (represented by four underscores) a user has filled in a string. For instance, when given the template ____ world, and the user's input of Hello world, it should return the array ["Hello"].

So far, I've cobbled together the below, but it has issues identifying the blanks:

function identifyBlanks(template, filledString) {
  // Split the template and filled string into arrays of words
  const templateWords = template.split(' ');
  const filledWords = filledString.split(' ');

  // Initialize an array to store the filled words
  const filledBlanks = [];

  // Iterate over the template and check for blanks
  for (let i = 0; i < templateWords.length; i++) {
    // Check if the template word contains a blank (indicated by multiple underscores)
    if (templateWords[i].includes('____')) {
      const blankIndex = templateWords[i].indexOf('____');
      
      // Find the corresponding filled word by matching the substring before and after the blank
      const filledWord = filledWords.find(word => {
        const wordBeforeBlank = word.substring(0, blankIndex);
        const wordAfterBlank = word.substring(blankIndex + 4); // 4 represents the length of '____'
        return templateWords[i].startsWith(wordBeforeBlank) && templateWords[i].endsWith(wordAfterBlank);
      });

      // Add the filled word to the array if found
      if (filledWord) {
        filledBlanks.push(filledWord);
      }
    }
  }

  return filledBlanks;
}

const template = "letters a____c";
const filledString = "letters abc";

const filledBlanks = identifyBlanks(template, filledString);
console.log(filledBlanks); // Output: ["b"]

There are a couple more edge cases I'm struggling with too - it should be able to recognize when a blank has been replaced by an empty string, as well as detecting blanks that are inside words, instead of surrounded by spaces. For instance, when given the template H____o ____ world! and the string Hello world!, it should return ["ell", ""].

Edit: The use case for this is to be able to reverse engineer a user's answer to a Python problem, where they are given a problem like

____ = input("Enter your name")
____(name)

and could answer it like

name = input("Enter your name")
print(name)

I then need to get the blanks they've entered at a later time. I'm aware there are better ways of implementing this (e.g. storing just the blanks they've entered, as opposed to their whole solution), but in the context of the system it's part of this isn't feasible.

英文:

I am writing a Javascript function to recognise the blanks (represented by four underscores) a user has filled in a string. For instance, when given the template ____ world, and the user's input of Hello world, it should return the array [&quot;Hello&quot;].

So far, I've cobbled together the below, but it has issues identifying the blanks

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

function identifyBlanks(template, filledString) {
  // Split the template and filled string into arrays of words
  const templateWords = template.split(&#39; &#39;);
  const filledWords = filledString.split(&#39; &#39;);

  // Initialize an array to store the filled words
  const filledBlanks = [];

  // Iterate over the template and check for blanks
  for (let i = 0; i &lt; templateWords.length; i++) {
    // Check if the template word contains a blank (indicated by multiple underscores)
    if (templateWords[i].includes(&#39;____&#39;)) {
      const blankIndex = templateWords[i].indexOf(&#39;____&#39;);
      
      // Find the corresponding filled word by matching the substring before and after the blank
      const filledWord = filledWords.find(word =&gt; {
        const wordBeforeBlank = word.substring(0, blankIndex);
        const wordAfterBlank = word.substring(blankIndex + 4); // 4 represents the length of &#39;____&#39;
        return templateWords[i].startsWith(wordBeforeBlank) &amp;&amp; templateWords[i].endsWith(wordAfterBlank);
      });

      // Add the filled word to the array if found
      if (filledWord) {
        filledBlanks.push(filledWord);
      }
    }
  }

  return filledBlanks;
}

const template = &quot;letters a____c&quot;;
const filledString = &quot;letters abc&quot;;

const filledBlanks = identifyBlanks(template, filledString);
console.log(filledBlanks); // Output: [&quot;b&quot;]

<!-- end snippet -->

There's a couple more edge cases I'm struggling with too - it should be able to recognise when a blank has been replaced by an empty string, as well as detecting blanks that are inside words, instead of surrounded by spaces. For instance, when given the template H____o ____ world! and the string Hello world!, it should return [&quot;ell&quot;, &quot;&quot;]

edit: The use case for this is to be able to reverse engineer a user's answer to a Python problem, where they are given a problem like

____ = ____(&quot;Enter your name&quot;)
____(name)

and could answer it like

name = input(&quot;Enter your name&quot;)
print(name)

I then need to get the blanks they've entered at a later time. I'm aware there are better ways of implementing this (e.g. storing just the blanks they've entered, as opposed to their whole solution), but in the context of the system it's part of this isn't feasible.

答案1

得分: 2

请查看有关相关问题的评论,https://stackoverflow.com/q/75704337,其中提到了一些注意事项。这些注意事项很重要。正如@trincot在他的评论中指出的那样,这永远不能完全精确。

你可以编写这样的函数:

const fillBlanks = (template, response, match = response.match(new RegExp(
  template.replace(/[/\-\\^$*+?.()|[\]{}]/g, '\$&') // https://stackoverflow.com/a/3561711
          .replace(/ /g, '\\s*')                     // 压缩空格 
          .replace (/____/g, (s) => `(.*)`),         // 添加捕获组
  "m"                                                 // 多行正则表达式
))) => match && match.slice(1)

console.log(fillBlanks('____ World!', 'Hello World!')) //=> ["Hello"]
console.log(fillBlanks('H____o ____World!', 'Hello World!')) //=> ["ell", ""]
  
const template = `____ = ____("Enter your name")
____(name)`

const answer = `name = input("Enter your name")
print(name)`

console.log(fillBlanks(template, answer)) //=> ["name", "input", "print"]

请注意,压缩空格可能会导致一些你不想要的匹配。我们可以移除它,但是"H____o ____ World!"至少有两个空格的情况将不会匹配只有一个空格的"Hello World!"。我不知道有什么好的解决办法。

英文:

See comments on a related question, https://stackoverflow.com/q/75704337 for some caveats. Those caveats are important. This can never be entirely precise, as @trincot points out in his comment.

You can write a function like this:

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

const fillBlanks = (template, response, match = response .match (new RegExp (
  template .replace(/[/\-\\^$*+?.()|[\]{}]/g, &#39;\$&amp;&#39;) // https://stackoverflow.com/a/3561711
           .replace(/ /g, &#39;\\s*&#39;)                     // condense spaces 
           .replace (/____/g, (s) =&gt; `(.*)`),         // add capture group
  &quot;m&quot;                                                 // multiline regex
))) =&gt; match &amp;&amp; match .slice (1)

console .log (fillBlanks (&#39;____ World!&#39;, &#39;Hello World!&#39;)) //=&gt; [&quot;Hello&quot;]
console .log (fillBlanks (&#39;H____o ____World!&#39;, &#39;Hello World!&#39;)) //=&gt; [&quot;ell&quot;, &quot;&quot;]

const template = `____ = ____(&quot;Enter your name&quot;)
____(name)`

const answer = `name = input(&quot;Enter your name&quot;)
print(name)`

console .log (fillBlanks (template, answer)) //=&gt; [&quot;name&quot;, &quot;input&quot;, &quot;print&quot;]

<!-- language: lang-css -->

.as-console-wrapper {max-height: 100% !important; top: 0}

<!-- end snippet -->

Note that the condensing of spaces might allow for some matches you don't want. We could remove it, but then &quot;H____o ____ World!&quot; with at least two spaces wouldn't match &quot;Hello World!&quot; with only one. I don't know of a good solution for that.

huangapple
  • 本文由 发表于 2023年5月22日 19:10:02
  • 转载请务必保留本文链接:https://go.coder-hub.com/76305550.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定