11

重複の可能性:
javascript から動的に関数パラメーター名/値を取得する方法

私は現在、関数からパラメーターの配列(値ではなく、引数は必要ありません)を取得しようとしているjavascript(node.js)のプロジェクトに取り組んでいます。現在、 Function.toString() を使用して関数文字列を取得し、それに対して正規表現を実行してパラメーター リストを取得しています。

次の単純な例を見てみましょう。

var myFunction = function (paramOne, paramTwo) { ... }

これに対して正規表現を実行し、文字列マジック (分割など) を実行すると、次のような配列が返されることが期待されます。

paramList = ['paramOne', 'paramTwo']

機能するものがありますが、JavaScriptで変数名に使用できるいくつかのファンキーな文字と、JavaScriptで複数の行で関数を定義できることを考えると、おそらく最善の解決策ではないと感じています。

これが私が現在持っているものです:

function.*[\w\s$]*(\((.*[\w\s,$]*)\))

これにより、グループ 1 で「一致」が得られ、次にグループ 2 で括弧なしのパラメーター リストが得られます。これはクールです。これは本当に私がやりたいことをするための最良の方法ですか? これに使用できるより良い正規表現はありますか? 私は本当に「より単純な」ものを探しているわけではありませんが、考えられるすべての状況を捉えることができるものを探しています。

どんな助けでも大歓迎です、そして前もって感謝します!

4

3 に答える 3

23

序文:これを処理する最善の方法は、単一の正規表現で処理しようとするのではなく、JavaScript パーサーを使用することです。正規表現をパーサーの一部にすることはできますが、1 つの正規表現でパーサーの作業を行うことはできません。JavaScript のシンタックス (ほとんどのプログラミング言語のシンタックスと同様) は、単純な正規表現で処理するには複雑すぎてコンテキストに依存します。JavaScript で書かれたオープンソースの JavaScript パーサーがいくつかあります。以下のものではなく、それらのいずれかを使用することを強くお勧めします。


最も簡単な方法は、最初のかっこのセットですべてをキャプチャし、それを使用split(/\s*,\s*/)して配列を取得することです。

例えば:

var str = "function(   one  ,\ntwo,three   ,   four   ) { laksjdfl akjsdflkasjdfl }";
var args = /\(\s*([^)]+?)\s*\)/.exec(str);
if (args[1]) {
  args = args[1].split(/\s*,\s*/);
}
console.log("args: ", args);

上記の仕組み:

  1. /\( *([^)]+?) *\)/最初の開き括弧 (正規表現では特別な\(ので) に一致するように使用し(、任意の量の空白が続き、その後に閉じ括弧以外のすべてをキャプチャするキャプチャ グループが続きます (ただし貪欲ではありません)。その後に任意の量の空白が続きます。続いてクロージング)

  2. 成功した場合は、 を使用し/\s*,\s*/て分割します。つまり、0 個以上の空白文字 ( \s*) の後にコンマが続き、その後に 0 個以上の空白文字が続くシーケンスで分割します (この空白が、私の例の関数の引数が非常に奇妙である理由です)。 .

例からわかるように、これは先頭の空白 ((最初の引数の後と前)、コンマの前後の空白、および末尾の空白 (改行を含む) を処理します。引数リスト内のコメントを処理しようとしないため、事態が著しく複雑になります。

注:上記は ES2015 のデフォルト パラメータ値を処理しません。これは任意の式である可能性があり、これには a を含む式が含まれます。) これは、検索を早期に停止することで上記の正規表現を破ります。

var str = "function(   one  ,\ntwo = getDefaultForTwo(),three   ,   four   ) { laksjdfl akjsdflkasjdfl }";
var args = /\(\s*([^)]+?)\s*\)/.exec(str);
if (args[1]) {
  args = args[1].split(/\s*,\s*/);
}
console.log("args: ", args);

JavaScript パーサーを使用します。:-)

于 2012-12-19T12:53:17.377 に答える
4

次のようにします。

var ar = str.match(/\((.*?)\)/);
if (ar) {
  var result = ar[0].split(",");
}

覚えて ?after * 貪欲でない検索を行います

于 2012-12-19T13:00:04.173 に答える
2

正規表現を使用することをお勧めします。

  • [match]/function[^(]*\(([^)]*)\)/は引数リストに一致します
  • [分割] /\W+/(最初の一致データの結果に対して) は、一致を params リストに分割します

したがって、コードは次のようになります。

var s = "function moo (paramOne, paramTwo) { alert('hello'); }";
var s2 = s.match(/function[^(]*\(([^)]*)\)/)[1];
var paramList = s2.split(/\W+/);
于 2012-12-19T13:10:44.247 に答える