10

次のコードでは、文字列sが1万文字または2万文字のように追加されると、Mathematicaカーネルのセグメンテーション違反が発生します。

s = "This is the first line.
MAGIC_STRING
Everything after this line should get removed.
12345678901234567890123456789012345678901234567890123456789012345678901234567890
12345678901234567890123456789012345678901234567890123456789012345678901234567890
12345678901234567890123456789012345678901234567890123456789012345678901234567890
12345678901234567890123456789012345678901234567890123456789012345678901234567890
12345678901234567890123456789012345678901234567890123456789012345678901234567890
...";

s = StringReplace[s, RegularExpression@"(^|\\n)[^\\n]*MAGIC_STRING(.|\\n)*"->""]

これは主にMathematicaのせいだと思います。バグレポートを提出しました。返答があれば、ここでフォローアップします。しかし、私はこれを愚かな/非効率的な方法で行っているのかどうかも疑問に思っています。そうでない場合でも、Mathematicaのバグを回避するためのアイデアをいただければ幸いです。

4

3 に答える 3

8

Mathematica はPCRE構文を使用するため、/sSinglelineDOTALL修飾子とも呼ば(?s)れます。適用したい式の部分の前に修飾子を追加するだけです。

次の正規表現のドキュメントを参照してください: (「詳細情報」というラベルの付いたセクションを展開してください)
http://reference.wolfram.com/mathematica/ref/RegularExpression.html

後続のすべての正規表現要素に対する次の設定オプション:
(?i)大文字と小文字を同等に扱う (大文字と小文字を区別しない)
(?m)^ と $ を行頭と行末に一致させる (複数行モード)
(?s)allow . 改行
(?-c) 未設定オプションに一致する

この変更された入力は、15,000 文字の長さの文字列を使用して、式と同じ出力を生成し、Mathematica 7.0.1 をクラッシュさせません (オリジナルはクラッシュしました)。

s = StringReplace[s,RegularExpression@".*MAGIC_STRING(?s).*"->""]

@AlanMooreが説明した理由から、少し高速になるはずです

于 2010-02-14T16:36:02.550 に答える
4

正規表現を最適化する最良の方法は、Mathematica の正規表現エンジンの内部に依存しますが、(.|\\n)*@Simon が述べたように、私は間違いなく を取り除きます。これは単なる交代ではありませんが、すべての選択肢が正確に 1 文字に一致する交代があるのは、ほとんどの場合間違いです。それが文字クラスの目的です。ただし、次の文字に一致するときにのみ破棄するために、一致するときに各文字をキャプチャします (括弧のため)。

Mathematica の正規表現ドキュメントを簡単に調べても、/s(Singleline または DOTALL) 修飾子のようなものは見つからないので、古い JavaScript スタンバイをお勧めします--空白または空白以外[\\s\\S]*すべてに一致します。また、正規表現の最後にアンカーを追加すると役立つ場合があります。$

"(^|\\n)[^\\n]*MAGIC_STRING[\\s\\S]*$"

しかし、あなたの最善の選択肢は、正規表現をまったく使用しないことでしょう。ここではそれらを必要とするものは何も見当たりません.Mathematica の通常の文字列操作関数を使用する方がはるかに簡単で効率的でしょう.

于 2010-02-13T22:45:57.117 に答える
2

Mathematica は優れた管理者向けのおもちゃですが、長い文字列に対する正規表現や、大量のデータ (または正確さが重要な場合) に対するあらゆる種類の計算など、深刻なことを Mathematica で実行しようとしないことをお勧めします。試行錯誤したものを使用してください。Visual F# 2010 は、5 ミリ秒と 1 行のコードでクラッシュせずに正しい答えを取得します。

> let str =
    "This is the first line.\nMAGIC_STRING\nEverything after this line should get removed." +
      String.replicate 2000 "0123456789";;
val str : string =
  "This is the first line.
MAGIC_STRING
Everything after this li"+[20022 chars]

> open System.Text.RegularExpressions;;
> #time;;
--> Timing now on

> (Regex "(^|\\n)[^\\n]*MAGIC_STRING(.|\\n)*").Replace(str, "");;
Real: 00:00:00.005, CPU: 00:00:00.015, GC gen0: 0, gen1: 0, gen2: 0
val it : string = "This is the first line."
于 2010-04-22T21:27:01.670 に答える