""
文字列の周囲のを削除したいです。
たとえば、文字列が次の場合、"I am here"
のみを出力しますI am here
。
ベストアンサー1
仮定:
var someStr = 'He said "Hello, my name is Foo"';
console.log(someStr.replace(/['"]+/g, ''));
これでうまくいくはずです... (すべての二重引用符を置き換えることが目的の場合)。
仕組みは次のとおりです:
['"]
は文字クラスであり、一重引用符と二重引用符の両方に一致します。これを に置き換えると、"
二重引用符のみに一致します。+
: 1 つ以上の引用符、文字、先行する文字クラスで定義される (オプション)g
:グローバルフラグ。これは、JS に正規表現を文字列全体に適用するように指示します。これを省略すると、1 つの文字のみが置き換えられます。
特定の文字列 (つまりペア) を囲む引用符を削除しようとすると、状況は少し複雑になります。 lookaround アサーションを使用する必要があります。
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 を参照
置換は で'$1'
、これは最初にキャプチャされたグループへの後方参照であり、[^" ]+
、または二重引用符で囲まれたすべてです。パターンは引用符と引用符で囲まれた内容の両方に一致しますが、引用符で囲まれた内容のみに置換するため、引用符は実質的に削除されます。つまり、
- some "string with" quotes
> が"string with"
-> に置換されますstring with
。引用符がなくなり、作業は完了です。
引用符が常に文字列の先頭と末尾にある場合は、次のように使用できます。
str.replace(/^"(.+(?="$))"$/, '$1');
または、二重引用符と一重引用符の場合は次のようになります。
str.replace(/^["'](.+(?=["']$))["']$/, '$1');
入力 の場合remove "foo" delimiting "
、出力は変更されませんが、入力文字列を に変更すると"remove "foo" delimiting quotes"
、出力は になりますremove "foo" delimiting quotes
。
説明:
^"
: は文字列の先頭^
と a に一致します"
。文字列が a で始まっていない場合"
、式はここですでに失敗しており、何も置き換えられません。(.+(?="$))
: 肯定先読みが真であれば、二重引用符を含むすべてのものに一致(およびキャプチャ)します。(?="$)
: 肯定的な先読みは上記とほぼ同じですが、文字列の末尾でなけれ"
ばならない$
ことを指定します ( === end)"$
: 終了引用符と一致しますが、キャプチャされません
置換は前と同じ方法で行われます。つまり、一致したもの (開始引用符と終了引用符を含む) を、その中にあるすべてのものに置き換えます。フラグ (global BTW 用)
を省略したことにお気付きかもしれませんg
。これは、文字列全体を処理しているため、この式は 1 回しか適用されないためです。
ほぼ同じことを行うより簡単な正規表現 (正規表現のコンパイル/適用方法には内部的な違いがあります) は次のようになります。
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 つの引数が必要で、最初の文字は部分文字列の開始オフセット、2 番目の文字はその長さです。最初の文字が必要ないのと同様に、最後の文字も必要ないため、その長さは ですstr.length - 2
。簡単です。
チップ:
ルックアラウンドアサーションの詳細こちらからご覧いただけます
正規表現は非常に便利です(そして楽しいと思います)が、最初は少し戸惑うかもしれません。ここに詳細とリソースへのリンクがありますこの件について。
まだ正規表現の使用に慣れていない場合は、次のものの使用を検討してください。
var noQuotes = someStr.split('"').join('');
文字列に引用符がたくさんある場合は、正規表現を使用するよりも速いかもしれません。