2017-08-09 17 views
-1

私はSpiceファイル形式を解析しなければならず、正規表現マッチングを選択して行を解析しました。このため私はTPerlRegExを選択しました。私は.subcktの処理で捕まった。 SubCircuitオブジェクトには、名前、ノード名リスト、パラメータ名と値のペアリストの属性があります。私はいくつかの(可能な)テストケースを書いたが、そのうちいくつかは失敗する。ソースコード:DelphiでPerlRegExでテキストを解析する

uses 
    PerlRegEx 
    ; 

{$R *.dfm} 

procedure TForm1.Button1Click(Sender: TObject); 
var 
    aPRE : TPerlRegEx; 
    i : integer; 

function getMatchingCaseIndex(subject_ : string) : integer; 
const 
    CONST_regexp_CubCircuitHeaders : array [0..3] of string = 
    ('.subckt\s([^\s]+)\s([\s\S]+)', 
     '.subckt\s([^\s]+)\s([^\s]+)\s([^=]+=[^\s]+)', 
     '.subckt\s([^\s]+)\s((?:[^\s]+)+)\sparams:\s([^\s]+\s[^\s]+)', 
     '.subckt\s([^\s]+)\s((?:[^\s]+)+)\sparams:\s([^=]+=[^\s]+)'); 
var 
    i : integer; 
begin 
    result := -1; 
    aPRE.subject := subject_; 
    i := length(CONST_regexp_CubCircuitHeaders); 
    while ((result < 0) and (i > 0)) do 
    begin 
    dec(i); 
    aPRE.regEx := CONST_regexp_CubCircuitHeaders[i]; 
    if (aPRE.match) then 
     result := i; 
    end; 
end; 

begin 
    aPRE := TPerlRegEx.create; 
    try 
    // Should return 0 
    // Test cases without any parameter definition 
    { 1} i := getMatchingCaseIndex('.subckt NAME NODE1'); 
    { 2} i := getMatchingCaseIndex('.subckt NAME NODE1 NODE2'); 
    // Should return 1 
    // Test cases when 'params:' does not inserted (name=value parameter definiion form expected) 
    { 3} i := getMatchingCaseIndex('.subckt NAME NODE1 name1=value1'); 
    { 4} i := getMatchingCaseIndex('.subckt NAME NODE1 name1=value1 name2=value2'); 
    { 5} i := getMatchingCaseIndex('.subckt NAME NODE1 NODE2 name1=value1'); 
    { 6} i := getMatchingCaseIndex('.subckt NAME NODE1 NODE2 name1=value1 name2=value2'); 
    // Should return 2 
    // Test cases when 'params:' inserted (name value parameter definition form) 
    { 7} i := getMatchingCaseIndex('.subckt NAME NODE1 params: name1 value1'); 
    { 8} i := getMatchingCaseIndex('.subckt NAME NODE1 params: name1 value1 name2 value2'); 
    { 9*} i := getMatchingCaseIndex('.subckt NAME NODE1 NODE2 params: name1 value1'); 
    {10*} i := getMatchingCaseIndex('.subckt NAME NODE1 NODE2 params: name1 value1 name2 value2'); 
    // Should return 3 
    // Test cases when 'params:' inserted (name=value parameter definition form) 
    {11} i := getMatchingCaseIndex('.subckt NAME NODE1 params: name1=value1 name2=value2'); 
    {12} i := getMatchingCaseIndex('.subckt NAME NODE1 params: name1=value1 name2=value2'); 
    {13*} i := getMatchingCaseIndex('.subckt NAME NODE1 NODE2 params: name1=value1 name2=value2'); 
    {14*} i := getMatchingCaseIndex('.subckt NAME NODE1 NODE2 params: name1=value1 name2=value2'); 
    finally 
    aPRE.Free; 
    end; 
end; 

テストケース(9,10)は、バック0の代わりに2及びテストケース(13,14)を通過する2つ(またはそれ以上)のノード名が前に定義された場合にはバック1の代わりに3を通過しますパラメータリスト。正規表現をすべてのテストケースに変更して正しい値を返すにはどうすればよいですか?

+1

が手元にTPerlRegExをお持ちでない - 私は 'System.RegularExpressions'が含まれていた前のバージョンであると思いますか? '((?:[^ \ s] +)+)'はちょうど '(\ S +)'でなければならず、 '.subckt'はおそらく' \ .subckt 'でなければなりません。 –

+0

@SebastianProske私はDelphi XE4を使用しています。そこには内部にregexpソリューションが組み込まれていますか?私はちょうどネット上のものを探しました。ほとんどの場合、パラメータリストの前にノード名が1つ以上必要であり、 '(\ S +)'はただ1つの世界にマッチしますね。関数の結果は期待されたものではないので、正規表現にはいくつかのバグがあるはずです。あなたの '\ .subckt'リフレクションは正しいです、thx – User007

+0

@SebastianProske組み込みのregexp実装をチェックアウトして、同じ値を返します。 (regexpsで提案された修正を加えたもの) – User007

答えて

0

OK。私は、次のように正規表現を変更し、テストケースのすべてが合格:

'\.subckt\s(\S+)\s((?:[^\s:]+\s*)+)', 
'\.subckt\s(\S+)\s((?:[^\s:]+\s*)+)\s([^=]+=\S+)', 
'\.subckt\s(\S+)\s((?:[^\s:]+\s*)+)\sparams:\s((?:\S+\s*)+)', 
'\.subckt\s(\S+)\s((?:[^\s:]+\s*)+)\sparams:\s([^=]+=\S+)');