2016-10-22 9 views
3

私は、文字列と一致するようにLPegパターンを書き込むしようとしている:LPegパターン

  • はその後
  • が二つが含まれていない文字の英数字の文字
  • で始まるを以上の連続したハイフン(例えば禁止しtest--string)参考のために

、私が探しているものと一致[a-zA-Z](-?[a-zA-Z0-9])*正規表現。

ここ

私は参考のために、と働いているコードです:

require "lpeg" 
P,R,C = lpeg.P,lpeg.R,lpeg.C 

dash = P"-" 
ucase = R"AZ" 
lcase = R"az" 
digit = R"09" 
letter = ucase + lcase 
alphanum = letter + digit 

str_match = C(letter * ((dash^-1) * alphanum)^0) 

strs = { 
    "1too", 
    "too0", 
    "t-t-t", 
    "t-t--t", 
    "t--t-t", 
    "t-1-t", 
    "t--t", 
    "t-one1", 
    "1-1", 
    "t-1", 
    "t", 
    "tt", 
    "t1", 
    "1", 
} 

for _,v in ipairs(strs) do 
    if lpeg.match(str_match,v) ~= nil then 
     print(v," => match!") 
    else 
     print(v," => no match") 
    end 
end 

が私の欲求不満に多くの、しかし、私は次の出力を得る:どのようなコードの出力にもかかわらず

1too  => no match 
too0  => match! 
t-t-t => match! 
t-t--t => match! 
t--t-t => match! 
t-1-t => match! 
t--t  => match! 
t-one1 => match! 
1-1  => no match 
t-1  => match! 
t  => match! 
tt  => match! 
t1  => match! 
1  => no match 

を、t-t--tt--t-tt--tは一致しません。

+1

を行う必要があります^ -1) *英数字)^ 0'!あなたは、 "グループには最大で1つのダッシュとそれに続く1つの英数字の可能性をグループ化します。これはすべて0回以上発生します。"だからあなたのパターンは、最初の手紙で失敗することができます。 – Youka

答えて

2

パターンletter * ((dash^-1) * alphanum)^0では、lpegは文字列の接頭辞との一致を試みます。あなたは
--ttトン

--t部分は太字で強調試合

TT
--t tは期待していなかった場合のためにあなたのパターンは正常に一致します。 lpeg.matchは、何も取得されなかった場合にパターンを使用して解析できた最後の位置(数値)を返します。上記の3つのケースでは、あなたが見ている誤った出力を説明するマッチングサブパッドがキャプチャされます。

各文字列を一度に1つずつ一致させるだけであれば、パターンを修正して、解析後に残りの文字が残っていないことを確認できます。

同様に任意のマッチが捕捉されます一緒にこの

stream_parse = re.compile 
[[ 
    stream_match <- ((str_match/skip_nonmatch) delim)* str_match? 
    str_match  <- { %a ('-'? %w)* } (&delim/!.) 
    skip_nonmatch <- !str_match (!delim .)* 

    delim   <- %s+ 
]] 

ような文法規則をスタック、ストリームマッチングまたはターゲット文字列内の全てのパターンの出現を見つけるためlpeg.reモジュール

re_pat = re.compile "{ %a ('-'? %w)* } !." 

を用い

str_match = C(letter * ((dash^-1) * alphanum)^0) * -1 

返されます。一致するものがない場合は、nilまたは文字列内のどこでパターンの解析が停止したかを示す数字が返されます。

編集:あなたがいない試合にnilを返すために、解析が必要な場合のために、文法にこの微調整は、 `((ダッシュで詳しく見てみましょうトリック

stream_parse = re.compile 
[[ 
    stream_match <- (str_match/skip_nonmatch+ &str_match)+ 
    str_match  <- { %a ('-'? %w)* } (&delim/!.) 
    skip_nonmatch <- !str_match (!delim .)* delim 

    delim   <- %s+ 
]]