在文本输入中替换错误使用“a”和“an”

时间:2015-12-23 16:51:40

标签: javascript regex

我有兴趣验证或自动更正textarea中英文文本块中不定冠词“a”和“an”的使用。

语法规则是文章的选择取决于开始下一个单词的声音。详情herehere。这看起来非常广泛,但是在先前的答案(How can I correctly prefix a word with "a" and "an"?)中有一个建议,即引用一个庞大的英文文本数据库来创建启发式,以推断在特定情况下使用的正确的不定冠词。 Eamon Nerbonne评论说他已经这样做了,那么我该如何将这个解决方案应用到这个实际的实现中呢?

到目前为止,我所使用的函数实现了语法规则中最简单的部分;当以下单词以元音开头时,它使用 ,否则使用 a 。它还尊重该文章的现有资本化。但在实际使用中,这是不实际的,因为该规则的例外情况非常普遍。例如,“a horse”是正确的,而“荣誉”和“HTTP地址”则不是。

如何扩展我的功能以正确处理文章后面的单词的实际发音,包括无声字母,首字母缩略词和“有时-y”?我不需要100%的准确度 - 比80%更好的东西足以改进我正在纠正的文本。

这是我的fixArticles()函数;请参阅代码片段以获取正在运行的示例。

function fixArticles( txt ) {
  var valTxt = txt.replace(/\b(a|an) (\w*)\b/gim, function( match, article, following ) {
    var newArticle = article.charAt(0);
    switch (following.charAt(0).toLowerCase()) {
      case 'a':
      case 'e':
      case 'i':
      case 'o':
      case 'u':
        newArticle += 'n'; // an
        break;
      default:
        // a
        break;
    }
    if (newArticle !== article) {
      newArticle = "<span class='changed'>" + newArticle + "</span>";
    }
    return newArticle+' '+following;

  });

  document.getElementById('output-text').innerHTML = valTxt.replace(/\n/gm,'<br/>');
}

function fixArticles( txt ) {
  var valTxt = txt.replace(/\b(a|an) (\w*)\b/gim, function( match, article, following ) {
    var newArticle = article.charAt(0);
    switch (following.charAt(0).toLowerCase()) {
      case 'a':
      case 'e':
      case 'i':
      case 'o':
      case 'u':
        newArticle += 'n'; // an
        break;
      default:
        // a
        break;
    }
    if (newArticle !== article) {
      newArticle = "<span class='changed'>" + newArticle + "</span>";
    }
    return newArticle+' '+following;

  });
  
  document.getElementById('output-text').innerHTML = valTxt.replace(/\n/gm,'<br/>');
}
input, label {
    display:block;
}
.changed {
  font-weight: bold;
}
<label for="input-text">Enter text</label>
<textarea id="input-text" cols="50" rows="5">An wise man once said: "A apple an day keeps the doctor away."
Give me an break.
I would like an apple.
My daughter wants a hippopotamus for Christmas.
It was an honest error.
Did a user click the button?
An MSDS (material safety data sheet) was used to record the data.
</textarea>
<input type="button" value="Fix a/an" onClick="fixArticles(document.getElementById('input-text').value)">
<hr>
<div id="output-text"/>

样本输入的预期输出为:

  

一位智者曾经说过:“一个苹果一个日让医生远离我。”
  给我 a 休息。
  我想要一个苹果   我女儿想要一只河马过圣诞节   这是一个诚实的错误   用户是否点击了按钮?   使用 MSDS(材料安全数据表)记录数据。

1 个答案:

答案 0 :(得分:4)

在对How can I correctly prefix a word with "a" and "an"?的轻率回答之后,Eamon Nerbonne按照给定的建议制作了一个有效的算法,可以在任何后续文本之前准确识别正确的不定冠词。所以感谢@JayMEE指针,它确实有帮助。

算法的实现超出了基本Q&amp; S的范围。答:您可以在Eamon的blog entryGitHub repository中阅读相关内容。但是,使用起来很简单!

以下是如何修改fixArticles()以使用简单的缩小版Eamon代码AvsAn-simple.min.js。请参阅JSFiddle Demo

function fixArticles(txt) {
  var valTxt = txt.replace(/\b(a|an) ([\s\(\"'“‘-]?\w*)\b/gim, function(match, article, following) {
    var input = following.replace(/^[\s\(\"'“‘-]+|\s+$/g, ""); //strip initial punctuation symbols
    var res = AvsAnSimple.query(input);
    var newArticle = res.replace(/^a/i, article.charAt(0));
    if (newArticle !== article) {
      newArticle = "<span class='changed'>" + newArticle + "</span>";
    }
    return newArticle + ' ' + following;
  });

  document.getElementById('output-text').innerHTML = valTxt.replace(/\n/gm, '<br/>');
}