【JavaScript】文字列として渡された数式を評価して計算する方法
文字列の数式を評価して計算結果を返す
本記事では、文字列形式で渡された数式を解析し、その計算結果を返すJavaScript関数の作成方法を解説します。
例えば、次のような数式が引数として与えられた場合を考えてみましょう。
const str = '1+23+4+5-30';
この場合、1 + 23 + 4 + 5 − 30 の計算が行われ、期待される出力は 3 となります。
実装コード
この問題を解決するコードは以下の通りです。
const str = '1+23+4+5-30';
const compute = (str = '') => {
let total = 0;
str = str.match(/[+\-]*(\.\d+|\d+(\.\d+)?)/g) || [];
while (str.length) {
total += parseFloat(str.shift());
};
return total;
};
console.log(compute(str));コードの解説
この関数の核となるのは、正規表現による数値の抽出です。使用している正規表現 /[+\-]*(\.\d+|\d+(\.\d+)?)/g の各要素は次のような役割を持っています。
[+\-]*: 数値の直前に付く符号(+ または -)が0個以上連続する部分にマッチします。(\.\d+|\d+(\.\d+)?): 「.5」のような小数点から始まる数値、あるいは「123」や「12.34」のような整数・小数にマッチします。gフラグ: 文字列全体から一致するすべてのパターンを配列として取得します。
これにより、例えば「1+23+4+5-30」という文字列は ["1", "+23", "+4", "+5", "-30"] という配列に分解されます。
その後、while ループ内で shift() を使って配列の先頭から順に要素を取り出し、parseFloat() で文字列を数値に変換しています。このとき「+23」は 23、「-30」は -30 として正しく解釈されるため、単純に合計を足し合わせるだけで計算が完了します。
このアプローチのメリット
文字列を評価する方法としては eval() を使う手段も考えられますが、eval() は任意のコードを実行できてしまうため、重大なセキュリティリスクを伴います。一方、この方法では正規表現で数値のみを厳密に抽出するため、悪意のあるコードが混入しても実行されることがなく、安全に計算処理を行えます。
なお、この実装が対応しているのは加減算のみです。乗除算や括弧を含む複雑な式を扱いたい場合は、演算子の優先順位を考慮したパーサーの実装が必要になります。
出力
コンソールに出力される結果は以下の通りです。
3
-
JavaScriptで指定した文字数に文字列を切り詰める方法
JavaScriptでは、長いテキストを一覧表示やプレビュー用に短く表示したい場面がよくあります。この記事では、文字列と数値を受け取り、指定された文字数を超える場合は文字列を切り詰めて末尾に「...」を付けて返す関数の実装方法を解説します。要件作成する関数は、文字列と数値の2つの引数を受け取ります。文字列の長さが指定された数値より大きい場合は、先頭から指定文字数分だけ切り取った文字列に「...」を連結して返します。切り詰める必要がない場合(元の文字列が指定文字数以下の場合)は、元の文字列をそのまま返します。コード例以下がその実装コードです。 { const { length: len
-
JavaScriptで演算子の優先順位を考慮した数式評価を実装する方法
問題文字列として与えられた数式を受け取り、その計算結果を数値として返すJavaScript関数を作成します。この関数では、以下の数学演算子をサポートする必要があります。除算 /(浮動小数点除算として扱う)加算 +減算 -乗算 *演算子は常に左から右へ評価され、* と / は + と - よりも優先的に処理されなければなりません。また、単項マイナス(負数の扱い)にも対応しています。アルゴリズムのポイントこの実装では、有名な「操車場アルゴリズム(Shunting Yard Algorithm)」の考え方を利用しています。これは、中置記法(人間が普段書く数式の形式)の式を、コンピュータが評価しやすい