我想从字符串中删除双引号

IT技术 javascript regex
2021-01-12 21:17:56

我想删除""周围的字符串。

例如,如果字符串是:"I am here"那么我只想输出I am here.

6个回答

假设:

var someStr = 'He said "Hello, my name is Foo"';
console.log(someStr.replace(/['"]+/g, ''));

这应该可以解决问题......(如果您的目标是替换所有双引号)。

这是它的工作原理:

  • ['"]是一个字符类,匹配单引号和双引号。您可以将其替换"为仅匹配双引号。
  • +:一个或多个引号,字符,由前面的字符类定义(可选)
  • g:全球标志。这告诉 JS 将正则表达式应用于整个字符串。如果您省略这一点,您将只替换一个字符。

如果您试图删除给定字符串周围的引号(即成对),事情会变得有点棘手。您必须使用环视断言:

var str = 'remove "foo" delimiting double quotes';
console.log(str.replace(/"([^"]+(?="))"/g, '$1'));
//logs remove foo delimiting quotes
str = 'remove only "foo" delimiting "';//note trailing " at the end
console.log(str.replace(/"([^"]+(?="))"/g, '$1'));
//logs remove only foo delimiting "<-- trailing double quote is not removed

正则表达式解释:

  • ": 文字,匹配任何文字 "
  • (: 开始捕获组。括号 ( ())之间的任何内容都将被捕获​​,并可用于替换值。
  • [^"]+: 字符类,匹配所有字符,"1 次或多次除外
  • (?="):零宽度(如未捕获)正向前瞻断言。前一个匹配仅在其后跟"文字时才有效
  • ):结束捕获组,我们已经捕获了开场闭幕之间的所有内容 "
  • ": 另一个文字,参见列表项之一

替换为'$1',这是对第一个捕获组的反向引用,即是[^" ]+,或双引号之间的所有内容。该模式匹配引号和它们之间的内容,但仅用引号之间的内容替换它,从而有效地删除它们。
它的作用是some "string with" quotes-> 替换"string with"为 -> string with行情消失,工作完成。

如果引号总是在字符串的开头和结尾,那么你可以使用这个:

str.replace(/^"(.+(?="$))"$/, '$1');

或者这对于双引号和单引号:

str.replace(/^["'](.+(?=["']$))["']$/, '$1');

使用 input remove "foo" delimiting ",输出将保持不变,但将输入字符串更改为"remove "foo" delimiting quotes",您最终将remove "foo" delimiting quotes作为输出。

解释:

  • ^": 匹配字符串的开头^和 a "如果字符串不以 a 开头",则表达式在此处已失败,并且不会替换任何内容。
  • (.+(?="$)): 匹配(并捕获)所有内容,包括一次或多次双引号,前提是正向预测为真
  • (?="$): 正向前瞻与上面的大致相同,只是它指定" 必须是字符串的结尾 ( $=== end )
  • "$: 匹配该结束引号,但不捕获它

替换的方式与之前相同:我们用其中的所有内容替换匹配项(包括开始和结束引号)。
您可能已经注意到我省略了g标志(对于全局 BTW),因为由于我们正在处理整个字符串,因此该表达式仅适用一次。
一个更简单的正则表达式几乎可以做同样的事情(正则表达式的编译/应用方式存在内部差异)是:

someStr.replace(/^"(.+)"$/,'$1');

和之前一样^""$匹配字符串开头和结尾的分隔引号,(.+)匹配中间的所有内容,并捕获它。我已经尝试过这个正则表达式,以及上面的那个(带有前瞻断言),不可否认,令我惊讶的是发现这个稍微慢了一点。我的猜测是,只要引擎确定"字符串末尾没有环视断言就会导致前一个表达式失败嗯,但如果这是您想要/需要的,请继续阅读

然而,在最后一种情况下,这样做更安全、更快、更易于维护并且更好:

if (str.charAt(0) === '"' && str.charAt(str.length -1) === '"')
{
    console.log(str.substr(1,str.length -2));
}

在这里,我正在检查字符串中的第一个和最后一个字符是否是双引号。如果是的话,我会substr用来切断第一个和最后一个字符。字符串是零索引的,所以最后一个字符是charAt(str.length -1). substr需要 2 个参数,其中第一个是子字符串开始的偏移量,第二个是它的长度。由于我们不想要最后一个字符,而不是我们想要第一个字符,所以长度是str.length - 2. 轻松。

小贴士

更多关于环视断言的信息可以在这里找到 正则
表达式非常有用(而且 IMO 很有趣),起初可能有点令人困惑。这里有更多详细信息,以及有关此问题的资源链接
如果您还不太习惯使用正则表达式,您可能需要考虑使用:

var noQuotes = someStr.split('"').join('');

如果字符串中有很多引号,这甚至可能比使用正则表达式更快

我认为someStr.replace(/^"(.+)"$/,'$1');应该使用.*而不是.+. 测试用例'""'例如'""'.replace(/^"(.+)"$/,'$1')return "",但'""'.replace(/^"(.*)"$/,'$1')返回 ``
2021-03-21 21:17:56
@rid:我进行了编辑,稍微解释了表达式的作用以及如何对其进行自定义
2021-03-28 21:17:56
str = str.replace(/^"(.*)"$/, '$1');

如果引号是字符串的第一个和最后一个字符,则此正则表达式将仅删除引号。例子:

"I am here"  => I am here (replaced)
I "am" here  => I "am" here (untouched)
I am here"   => I am here" (untouched)

如果字符串保证在开头和结尾有一个引号(或任何其他单个字符),您想删除它:

str = str.slice(1, -1);

slice 开销比正则表达式少得多。

令人惊讶的是,这已经被否决了,因为如果您正在处理 RDF 文字,这正是您需要的那种“快速”操作(例如,在 N3 中,URI 通常表示为 like ,<uri>而文字则表示为"literal")。所以这是一个赞成票。;)
2021-03-12 21:17:56
它删除了 "" 但也删除了两端的字符
2021-03-23 21:17:56
(特别是因为原始问题说他们想删除字符串周围的引号。)
2021-04-06 21:17:56
为什么投反对票?'"我在这里"'.slice(1, -1) -> '我在这里'!
2021-04-07 21:17:56
这应该是公认的答案,因为它完全按照要求执行,并且有效执行。
2021-04-09 21:17:56

如果你可以控制你的数据并且你知道你的双引号包围了字符串(所以不要出现在字符串中)并且字符串是一个整数......说:

"20151212211647278"

或类似的,这很好地删除了周围的引号

JSON.parse("20151212211647278");

不是一个普遍的答案,但对于利基需求来说很光滑

不...在当前最新版本的 FireFox 上运行良好
2021-03-13 21:17:56
JSON.parse("20151212211647278dfvs"); SyntaxError: Unexpected token d in JSON at position 17
2021-03-13 21:17:56
这将在 FireFox 上出错:SyntaxError: JSON.parse: JSON 数据第 1 行第 1 列的意外字符
2021-03-28 21:17:56
我收到一个错误 SyntaxError: Unexpected token < in JSON at position 0
2021-04-08 21:17:56
JSON.parse("{123123}"); 这会让你的答案大打折扣
2021-04-10 21:17:56

如果您只想删除边界引号:

function stripquotes(a) {
    if (a.charAt(0) === '"' && a.charAt(a.length-1) === '"') {
        return a.substr(1, a.length-2);
    }
    return a;
}

如果字符串看起来不像"text in quotes".

使用a.charAt(x),如果你想<ECMA5支持(f.ex IE7)。
2021-03-30 21:17:56