用引号替换双引号 [英] Replace double quotes by quotation marks

查看:63
本文介绍了用引号替换双引号的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在寻找一种方法,用用户输入中的更正引号替换引号。

I am looking for a way to replace the quotes with "corrected" quotations marks in an user input.

想法

这是一个简短显示原则的片段:

对于报价,正确的报价有一个开头和收盘,因此需要以良好的方式进行更换。

Here is a snippet briefly showing the principle:
For quotes, the "correct" ones have an opening " and a closing ", so it needs to be replaced in the good way.

$('#myInput').on("keyup", function(e) {
  // The below doesn't work when there's no space before or after.
  this.value = this.value.replace(/ "/g, ' "');
  this.value = this.value.replace(/" /g, '" ');
});

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<textarea id="myInput"></textarea>

但上述情况不起作用在所有情况下。

例如,当引用的单词位于句子或行的开头或结尾时。

But the above is not working in all cases.
For example, when the "quoted word" is at the very beginning or the very end of a sentence or a line.

示例

可能的输入(注意,法语里面!:)):
$ b $b⋅我很开心! Çayest,j'aiosé,et monâmesœurétaitaurendez-vous ...
$ b $b⋅符号上写着:有些文字有些文字有些文字。并且注意这里的空间!
$ b $b⋅Inc或rectquotes should不能被替换。
$ b $b⋅我说:如果它适用于'单打' 我也更喜欢它!

Possible inputs (beware, french inside! :)) :
⋅ I'm "happy" ! Ça y est, j'ai "osé", et mon "âme sœur" était au rendez-vous…
⋅ The sign says: "Some text "some text" some text." and "Note the space here !"
⋅ "Inc"or"rect" quo"tes should " not be replaced.
⋅ I said: "If it works on 'singles' too, I'd love it even more!"

正确的输出:
$ b $b⋅我很开心! Çayest,j'aiosé,et monâmesœurétaitaurendez-vous ...
$ b $b⋅标志上写着:有些文字有些文字有些文字。和注意空间在这里!
$ b $b⋅Inc或rectquotes should不能被替换。
$ b $b⋅我说:如果它也适用于'单身',我我爱得更多!

Correct outputs:
⋅ I'm "happy" ! Ça y est, j'ai "osé", et mon "âme sœur" était au rendez-vous…
⋅ The sign says: "Some text "some text" some text." and "Note the space here !"
⋅ "Inc"or"rect" quo"tes should " not be replaced.
⋅ I said: "If it works on ‘singles’ too, I'd love it even more!"

输出不正确:
$ b $b⋅标志上写着:有些文字有些文字有些文字。和[...]

为什么不正确:

→报价结尾与收盘价之间应该没有空格。

→应该有在一个引号和一个单词之间的空格。

→一个单词和一个开头的引号之间应该有一个空格。

→开头报价之间应该没有空格标记及其报价。

Incorrect outputs:
⋅ The sign says: "Some text "some text" some text." and […]
Why it is incorrect:
→ There should be no space between the end of a quotation and its closing mark.
→ There should be a space between a closing quotation mark and a word.
→ There should be a space between a word and an opening quotation mark.
→ There should be no space between an opening quotation mark and its quotation.

需求

怎样才能有效轻松地更换在所有这些情况下引用?

如果可能的话,我也希望解决方案能够纠正引号,即使我们在输入整个后添加句子。

How could it be possible to effectively and easily replace the quotes in all those cases?
If possible, I'd also like the solution to be able to "correct" the quotes even if we add them after the typing of the whole sentence.

请注意,我不能(不能)在正则表达式中使用单词分隔符\ b,因为重音字符,例如é不幸的是,或ü被视为分词。(来源: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions

Note that I don't (can't) use the word delimiter "\b" in a regex because the "accented characters, such as "é" or "ü" are, unfortunately, treated as word breaks." (source: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions)

当然,如果没有其他解决方案,我会想出一个我认为是单词分隔符的列表并在正则表达式中使用它。但我更喜欢有一个很好的工作功能而不是一个清单!

Of course, if there is no other solution, I'll come up with a list of what I consider a word delimiter and use it in a regex. But I'd prefer to have a nice working function rather than a list!

任何想法都会受到赞赏。

Any idea would be appreciated.

推荐答案

我得到了一个最终满足我所有需求的解决方案。

我承认它比TJ的复杂得多,这对于简单来说非常完美案例。

I got a solution that finally fits all my needs.
I admit it is a lot more complicated than T.J.'s one, which can be perfect for simple cases.

请记住,我的主要问题是使用 \b 因为带有重音符号而无法使用。< br>
我能够通过使用本主题的解决方案摆脱这个问题:

在JavaScript中删除字符串中的重音符号/变音符号

Remember, my main problem was the impossilibity to use \b because of the accented characters.
I was able to get rid of that issue by using the solution from this topic:
Remove accents/diacritics in a string in JavaScript

之后,我使用了修改后的函数从这里的答案中获得了很大的启发...

如何在JavaScript中替换特定索引处的字符?

After that, I used a modified function highly inspired from the answer here…
How do I replace a character at a particular index in JavaScript?

...并且非常艰难,与RegEx一起玩很多以最终获得该解决方案:

… and had a very hard time, playing a lot with RegEx to finally get to that solution:

var str_orig = `· I'm "happy" ! Ça y est, j'ai "osé", et mon "âme sœur" était au rendez-vous…
· The sign says: "Some text "some text" some text." and "Note the space here !"
⋅ "Inc"or"rect" quo"tes should " not be replaced.
· I said: "If it works on 'singles' too, I'd love it even more!"
word1" word2"
word1 word2"
"word1 word2
"word1" word2
"word1" word2"
"word1 word2"`;

// Thanks, exactly what I needed!
var str_norm = str_orig.normalize('NFD').replace(/[\u0300-\u036f]/g, '');

// Thanks for inspiration
String.prototype.replaceQuoteAt = function(index, shift) {
  const replacers = ""‘"’";
  var offset = 1 * (this[index] == "'") + 2 * (shift);
  return this.substr(0, index) + replacers[offset] + this.substr(index + 1);
}

// Opening quote: not after a boundary, not before a space or at the end
var re_start = /(?!\b)["'](?!(\s|$))/gi;
while ((match = re_start.exec(str_norm)) != null) {
  str_orig = str_orig.replaceQuoteAt(match.index, false);
}

// Closing quote: not at the beginning or after a space, not before a boundary
var re_end = /(?<!(^|\s))["'](?!\b)/gi;
while ((match = re_end.exec(str_norm)) != null) {
  str_orig = str_orig.replaceQuoteAt(match.index, true);
}

console.log("Corrected: \n", str_orig);

以下是一个带有 textarea 的工作示例的片段。

我刚刚创建了第一个代码段的代码函数,我在插入符号位置使用子字符串来过滤函数的调用(避免在每个字符输入上调用它) :

And below is a snippet of a working example with a textarea.
I've just created a function of the code of the first snippet, and I'm using a substring around the caret position to filter the calling of the function (that avoids calling it on every character input):

String.prototype.replaceQuoteAt = function(index, offset) {
  const replacers = ""‘"’";
  var i = 2 * (offset) + 1 * (this[index] == "'");
  return this.substr(0, index) + replacers[i] + this.substr(index + 1);
}

function replaceQuotes(str) {
  var str_norm = str.normalize('NFD').replace(/[\u0300-\u036f]/g, '');
  var re_quote_start = /(?!\b)["'](?!(\s|$))/gi;
  while ((match = re_quote_start.exec(str_norm)) != null) {
    str = str.replaceQuoteAt(match.index, false);
  }
  var re_quote_end = /(?<!(^|\s))["'](?!\b)./gi;
  while ((match = re_quote_end.exec(str_norm)) != null) {
    str = str.replaceQuoteAt(match.index, true);
  }
  return str;
}

var pasted = 0;
document.getElementById("myInput").onpaste = function(e) {
  pasted = 1;
}

document.getElementById("myInput").oninput = function(e) {
  var caretPos = this.selectionStart; // Gets caret position
  var chars = this.value.substring(caretPos - 2, caretPos + 1); // Gets 2 chars before caret (just typed and the one before), and 1 char just after
  if (pasted || chars.includes(`"`) || chars.includes(`'`)) { // Filters the calling of the function
    this.value = replaceQuotes(this.value); // Calls the function
    if (pasted) {
      pasted = 0;
    } else {
      this.setSelectionRange(caretPos, caretPos); // Restores caret position
    }
  }
}

#myInput {
  width: 90%;
  height: 100px;
}

<textarea id="myInput"></textarea>

它似乎适用于我能想象的所有权利现在。

函数在以下情况下正确替换引号:
$ b $b⋅定期输入,
$ b $b⋅在输入文本后添加引号,

⋅粘贴文本。

It seems to work with all I can imagine right now.
The function correctly replaces the quotes when:
⋅ typing regularly,
⋅ adding quotes after we typed the text,
⋅ pasting text.

它取代了双引号和单引号。

It replaces both the double and the singles quotes.

无论如何,因为我是ñ如果您注意到可能不需要的行为或改善表达方式,请随时注释RegEx专家。

Anyway, as I am not a RegEx expert at all, please feel free to comment if you notice a behaviour that may be unwanted, or a way to improve the expressions.

这篇关于用引号替换双引号的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆