この記事は、簡単な文字列の面接問題から始まり、文字列のいくつかのメソッドと細部に焦点を当てています。
最近、面接問題に出くわしました。面白いと思いましたが、簡単ながらも深い考えを呼び起こします。問題は次のようなものです:文字列をキャメルケースに変換するメソッドを書いてください。例:border.bottom.color -> borderBottomColor。
文字列配列の操作#
ほとんどの人は、このようなメソッドを書くことができるでしょう。文字列を処理し、新しい文字列に結合します。主に文字列のいくつかの API を使用し、charAt (n) を使用して文字列の n 番目のインデックスの文字を取得することもできます。
function tranformStr(str) {
var strArr = str.split(".");
for (var i = 1; i < strArr.length; i++) {
strArr[i] = strArr[i].charAt(0).toUpperCase() + strArr[i].substring(1);
}
return strArr.join("");
}
正規表現#
2 番目の方法は、正規表現を使用して問題を解決するものです。実際には、これは文字列の replace メソッドと正規表現の組み合わせですが、難点は replace メソッドの理解にあります。
function transformStr(str) {
var re = /\.(\w)/g;
return str.replace(re, function(match, p1) {
return p1.toUpperCase();
});
}
上記の 2 つの方法からわかるように、正規表現を使用するとコードの量が少なくなりますが、正規表現と replace メソッドの理解がより高度な要求をもたらします。次に、replace メソッドのいくつかの API をまとめます。
replace の使用方法#
str.replace(regexp|substr, newSubStr|function)
replace メソッドの第 1 引数は、正規表現または文字列にすることができます。
- regexp(pattern)
正規表現(RegExp)オブジェクトまたはそのリテラル。この正規表現に一致する内容は、第 2 引数の返り値で置き換えられます。
- substr(pattern)
置き換えられる文字列。正規表現ではなく、文字列として扱われます。最初の一致のみが置き換えられます。
replace メソッドの第 2 引数は、文字列または関数にすることができます。
- newSubStr(replacement)
元の文字列の一致した部分を置き換えるための文字列。この文字列には特殊な変数名を挿入することができます。以下の文字列を引数として使用する方法を参照してください。
- function(replacement)
一致した結果に基づいて新しいサブストリングを作成する関数。この関数の返り値が一致した結果に置き換えられます。以下の関数を引数として使用する方法を参照してください。
replace メソッドは、呼び出し元の文字列自体を変更せず、新しい置き換え後の文字列を返します。
グローバル検索と置換を行う場合、正規表現には g フラグを含める必要があります。
文字列を引数として使用する方法#
第 2 引数が文字列の場合、置換文字列には次の特殊な変数名を挿入できます:
変数名 | 代表する値 |
---|---|
$$ | $ を挿入します。 |
$& | 一致した部分文字列を挿入します。 |
$` | 一致した部分文字列の前の内容を挿入します。 |
$' | 一致した部分文字列の後の内容を挿入します。 |
$n | 第 1 引数が RegExp オブジェクトであり、n が 0 から 99 までの非負整数である場合、n 番目の括弧に一致した文字列を挿入します。 |
以下は特殊な変数名の具体的な使用例です:
"border.bottom.color".replace(/\.(\w)/g, "$$");
// border$ottom$olor
"border.bottom.color".replace(/\.(\w)/g, "$&");
// border.bottom.color
"border.bottom.color".replace(/\.(\w)/g, "$`");
// borderborderottomborder.bottomolor
"border.bottom.color".replace(/\.(\w)/g, "$1");
// borderbottomcolor
関数を引数として指定する方法#
第 2 引数が関数の場合、一致した後にその関数が実行されます。関数の返り値が置き換え文字列として使用されます。(注意:上記で説明した特殊な置換パラメータはここでは使用できません。)また、第 1 引数が正規表現であり、グローバルマッチモードである場合、このメソッドは複数回呼び出され、各一致ごとに呼び出されます。
変数名 | 代表する値 |
---|---|
match | 一致した部分文字列。($& に対応) |
p1,p2, ... | replace () メソッドの第 1 引数が RegExp オブジェクトであり、n が 0 から 99 までの非負整数である場合、n 番目の括弧に一致した文字列を表します。($1,$2 などに対応) |
offset | 一致した部分文字列が元の文字列内でのオフセット値です。(例:元の文字列が "abcd" で、一致した部分文字列が "bc" である場合、このパラメータは 1 になります) |
string | 一致した元の文字列です。 |
注意:正確なパラメータの数は、replace () の第 1 引数が正規表現オブジェクトであり、その正規表現にいくつの括弧が含まれているかに依存します。
記事の最初の問題では、. の後に続く最初の文字をマッチさせ、大文字に変換する必要があります。具体的な実装コードは次のようになります:
function transformStr(str) {
var re = /\.(\w)/g;
return str.replace(re, function(match, p1) {
return p1.toUpperCase();
});
}
まず、re という正規表現を宣言し、. の後に括弧が続くものをマッチさせます。この括弧はキャプチャグループと呼ばれ、マッチした内容は第 2 引数で使用するために記憶されます。括弧内の \w は単一の文字(文字、数字、アンダースコア)にマッチし、[A-Za-z0-9] と同じです。第 2 引数は関数であり、最初の文字列 match はマッチした文字列です。上記の例では.b と.c になります。p1 は最初の括弧にマッチした文字列に対応し、b と c に対応します。関数内で p1 を大文字に変換し、replace が生成するのは新しい文字列なので、return で返します。