共通文字列パターンは、これはエスケープされた二重引用符(\"
)とバックスラッシュ(\\
)が含まれた文字列にマッチします
\"([^"\\\n]|\\(.|\n))*\"
です。 \\(.|\n)
を使用して、バックスラッシュの後の任意の文字を許可します。一部のバックスラッシュシーケンスは1文字(\x40
)よりも長いですが、最初の文字の後に英数字以外の文字は含まれていません。
入力にWindowsの行末(CR-LF)が含まれている可能性があります。この場合、バックスラッシュに改行が直接続くことはありません。キャリッジリターンが続きます。あなたは(より適切であるかもしれない)ではなく、エラーを投げるよりも、その入力を受け付けるようにしたい場合は、明示的に実行する必要があります。
\"([^"\\\n]|\\(.|\r?\n))*\"
しかし、文字列が何を表すかの文字列と理解を認識は、二つの異なるものです。通常、コンパイラは、文字列の表現をバイトシーケンスに変換する必要があります。たとえば、\n
をバイト10に変換し、バックスラッシュした改行を削除する必要があります。
このタスクは、開始条件を使って(f)lexスキャナで簡単に実行できます。 (もちろん、別の字句スキャナを使用して文字列を再スキャンすることもできます)。
また、エラー処理について考える必要があります。エスケープされていない改行(Cのように)で文字列を禁止すると、終了文字の前に改行がある未終端の文字列の可能性があります。文字列が正しく閉じられていなければ、ファイルの最後にも同じことが起こります。
1文字のフォールバックルールがある場合、終了していない文字列の開始引用符を認識します。これは、文字列の内容をプログラム・テキストとしてスキャンして、カスケード・エラーにつながるため好ましくありません。エラーリカバリを試行していない場合は、問題はありませんが、そうでない場合は、少なくとも改行文字まで、異なるパターンを使用して、終端されていない文字列を認識してください。
なぜ、より読みやすい '\ n'ではなく、{NEWLINE}(値が表示されない)という定義を使用していますか?それはあなたのコードを読みにくくし、質問を答えるのが難しくなります。なぜなら、おそらく不必要な定義のエラーと関係している可能性があるからです。また、文字クラスの中で引用符をエスケープする必要もありません( '[...]')。 – rici
これまで私のコードでは、NEWLINE \ nというルールを書いていました。だから私が必要としたところでは、私はNEWLINEを書きました。そして、私は文字クラスの中で引用符をエスケープする必要はありません。 – sphoenix
あなたのコードを書く方法は、もちろんあなたの決断です。しかし、定義を使用する場合は、それをあなたの質問に含める必要があります。それ以外の場合、実際の定義がどのようにわかるでしょうか?質問のコードは自己完結型でなければなりません。定義が正しければ、正規表現もそうであり、問題はあなたの入力の末尾の空白と関係している可能性があります。あなたのルールの他の場所でも、それはちょっと奇妙なことですが。 [mcve]を提供する方が常に良いです。 – rici