2016-04-03 15 views
1

nodejsアプリで2MB以上のアップロードファイルを使用しようとしました。
クライアント側FileReader apiを使用してbase64を保存した後、FormDataを渡します。正規表現にマッチする遅い

私の問題は、以下のようなので、遅いサーバー側のコードで、私はどの部分を見つけることconsole.log試みを入れて、より大きなサイズのファイルをアップロードする際に、
が 任意の提案がどのようにこれを改善するために...正規表現matchで立ち往生ようですか?ファイルbase64エンコード不要であるmultipart/form-data要求で送信

https://regex101.com/r/qS2lB2/1

... 
console.log(image.data_base64); 
// 'data:image/jpeg;base64,/9j/4AAQSkZJRgABAgEASABIAAD/7QAsUGhvd ... 
var matches = image.data_base64.match(/^data:.+\/(.+);base64,(.*)$/); 
console.log('done'); // slow 

var fileExtension = matches[1]; 
var base64 = matches[2]; 
var buffer = new Buffer(base64, 'base64'); 

... 
yield Promise.resolve(filesystem().writeFile(temporaryFilePath, buffer)); 
+1

代わりに 'split'を使うことができます。例: 'image.data_base64.split(/ [:;、] /)[1]; // mime type'; – Lewis

+0

返信ありがとうございます。上記の正規表現よりも高速に分割されます – user1575921

+1

['^ data:[^ \ /] + \;([^;] +); base64、(。*)$'](https:// regex101。 com/r/cX0dC1/1)は、多くのバックトラックを伴う貪欲なドットマッチングパターンではなく、2つの最初のキャプチャグループでネゲートされた文字クラスを使用します。 –

答えて

1

何らかの理由で正規表現を使用したい場合は、非後方の.+サブパターンをバックトラックがはるかに少ない適切なネゲートされた文字クラスに置き換えることで、パフォーマンスを向上させることができます。

使用

/^data:[^\/]+\/([^;]+);base64,(.*)$/ 

regex demoを参照してください。

説明:

  • ^ - 文字列
  • data:の開始 - リテラル文字列data:
  • [^\/]+ - /
  • \/以外1+文字 - リテラルスラッシュ
  • ([^;]+) - グループ1:以外の1文字以上
  • ;base64, - リテラル文字列;base,
  • (.*) - グループ2:0+任意の文字が、改行
  • $ - 文字列の末尾。
+0

ありがとうございました! – user1575921

+1

バックトラックとは、貪欲なパターンが一致するすべてのテキスト( '。+'ですべての行と一致する)を取得し、その後のサブパターンの文字に対応しようとすることです。したがって、文字列が何らかの方法で区切られている場合、パターン内の '。+'は良い考えではありません。このような場合、デリミタが1文字の場合、ネゲートされた文字クラスが最適です。デリミタが2以上の長さのcharの場合、遅延ドットマッチングまたは展開されたパターンを使用します(ループ手法の展開)。説明のために –

0

FileReaderには.readAsArrayBuffer()メソッドがあり、formData.append()に直接渡すことができる生データ(ArrayBufferとして)を提供します。

+0

これは、base64を他のjsonオブジェクトに挿入したいからです。 – user1575921

+0

その場合、別の 'formData.append()'を使って別のJSONデータを別の部分として送信するほうが良いでしょう。複数のフィールド(例えば、 '' "foo": "bar"、 "baz": "quux"} 'でパートを追加するのではなく、' formData.append( 'foo'、 'bar'); formData .append( 'baz'、 'quux'); ')。 – mscdex

+0

返信ありがとうございます。私は '' image ":{" list: "{" "id": "int"、 "description": "text"、 "base64": "base64" 、{}、{}、{}}} 'あなたはbase64と他のものを分けるべきだと提案しています、なぜですか? – user1575921

1

追加の長さは、正規表現が通過する必要がある文字列が多いことを意味します。

data:image/jpeg;base64,/9で始まる文字列に(regex101.com、PHPモードを使用して)あなたの正規表現をテストする:

文字が追加|ステップ

0 | 63 
1 | 68 
2 | 73 
10 | 113 
100 | 563 

各追加文字は5ステップです。(563のステップを踏むcharacters added=100に基づく)正規表現に

を修正する方法

  • あなたの最大の問題は、との最初のものを交換.+

    • ですか。+?

ステップ248から34にそれを取る.+?を有する第2の交換
  • ステップ248にそれを取るパフォーマンスの原因は
  • 致命的なバックトラックを発行します。 .+は文字列全体を食べてしまいます。さらに文字を見つける必要がある場合は、文字を1つずつ解放して戻ってくる必要があります。 .+?は遅延しているため、可能な限り少ない文字数を消費して正規表現のASAPに移行しようとします。

    +0

    ありがとう! – user1575921