Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

An error occurred while using case-insensitive option (?i) . #158

Open
Fzok4234 opened this issue May 14, 2022 · 5 comments
Open

An error occurred while using case-insensitive option (?i) . #158

Fzok4234 opened this issue May 14, 2022 · 5 comments

Comments

@Fzok4234
Copy link

Fzok4234 commented May 14, 2022

Regex pattern :
(?iu)(?>(?:)|(?:@\A(?>(?<varNameFirstChar>[_\p{Lu}\p{Ll}\p{Lt}\p{Lm}\p{Lo}])|(?<varNameBodyChar>(?>\g<varNameFirstChar>|[\p{Nd}]))|(?<varName>(?<!\g<varNameBodyChar>)\g<varNameFirstChar>\g<varNameBodyChar>*+))))\g<varName>

cf. https://www.maruo.co.jp/hidesoft/2/x39719_.html?a=0#39719

@tonco-miyazawa
Copy link

  1. 正規表現のみで大文字小文字を無視。
    検索パターン = (?#hmonig)(?#lookbehind)(?iu)(?#psvarname)\g<varName>
    大文字/小文字の区別 = 有効
    結果 = エラー 122

このエラーを以下のもので回避出来ました。

---------------- .HmJreSelect -------------------

[DllSelector]
(?#hmonig)=hmonig.dll

[ReplaceRegExp]
(?#psvarname)=(?<varNameFirstChar>[_\p{Lu}\p{Ll}\p{Lt}\p{Lm}\p{Lo}]){0}(?<varNameBodyChar>(?>\g<varNameFirstChar>|\p{Nd})){0}(?<varName>(?<![_\p{Lu}\p{Ll}\p{Lt}\p{Lm}\p{Lo}\p{Nd}])\g<varNameFirstChar>\g<varNameBodyChar>*+){0}

---------------- .HmJreSelect -------------------

後ろ読み (?<! ) の中身がエラーの原因になっていたので \g<> や | を 使わずに文字クラス1つにまとめて書きました。
この正規表現が期待通りのマッチをするのかどうかは当方には分からないのでお試し下さい。

  1. 検索ダイアログのみで大文字小文字を無視。
    検索パターン = (?#hmonig)(?#lookbehind)(?u)(?#psvarname)\g<varName>
    大文字/小文字の区別 = 無効
    結果 = エラー 217

  2. 検索ダイアログと正規表現の両方で大文字小文字を無視。
    検索パターン = (?#hmonig)(?#lookbehind)(?iu)(?#psvarname)\g<varName>
    大文字/小文字の区別 = 無効
    結果 = エラー 217

上記の .HmJreSelect でもこの2つのエラーは改善されません。
つまり上記の .HmJreSelect は

大文字/小文字の区別 = 有効

..の場合のみ使えます。 このエラーが何故出るのかは秀丸エディタのユーザーでない自分には分かりません。

上記の正規表現では {0} を使った定義に書き換えていますが、元の正規表現でも (?<! ) の中身を同じものに
書き換えるだけで 「エラー 122」 は出なくなります。

@Fzok4234
Copy link
Author

Thank you for providing the solution.
However, since we will have to write the same pattern _\p{Lu}\p{Ll}\p{Lt}\p{Lm}\p{Lo} multiple times, it will hinder maintenance. Therefore, we will use it as a temporary measure.

@tonco-miyazawa
Copy link

同じものを1回書くだけで済むようにしてみました、戻り読み (?<! ) の代わりに \K を使っています。

[DllSelector]
(?#hmonig)=hmonig.dll

[ReplaceRegExp]
(?#psvarname)=(?<varNameFirstChar>[_\p{Lu}\p{Ll}\p{Lt}\p{Lm}\p{Lo}]){0}(?<varNameBodyChar>(?>\g<varNameFirstChar>|[\p{Nd}])){0}(?<varName>(?:^|(?!\g<varNameBodyChar>).\K)\g<varNameFirstChar>\g<varNameBodyChar>*+){0}

検索ダイアログに以下のものを入力して検索した場合、

(?#hmonig)(?#lookbehind)(?iu)(?#psvarname)\g<varName>

展開された正規表現は以下のようになります。( 改行とタブを入れて見やすくしています )

(?iu)

(?<varNameFirstChar>
	[_\p{Lu}\p{Ll}\p{Lt}\p{Lm}\p{Lo}]
){0}

(?<varNameBodyChar>
	(?>
		\g<varNameFirstChar>
	|
		[\p{Nd}]
	)
){0}

(?<varName>
	(?:
		^
	|
		(?!\g<varNameBodyChar>).\K
	)
	\g<varNameFirstChar>
	\g<varNameBodyChar>*+
){0}

\g<varName>

本来は \G も使えばヒットする単語が2個以上連続している場合でも正しくマッチさせられるのですが
秀丸の検索ダイアログにある「上検索」「下検索」ボタンを押したときの挙動が変わってしまうので使うのをやめました。

「上検索」「下検索」ボタンを押したときの \G は検索開始位置にもマッチする仕様になっているようで、
本来はマッチさせたくない位置にもマッチしてしまいます。

「上検索」「下検索」ボタンを使うことが無く、強調表示のみに使う目的ならば正規表現に \G を使えます。
その場合は以下のように \G のための分岐を追加して下さい。

	(?:
		^
	|
		\G
	|
		(?!\g<varNameBodyChar>).\K
	)

※ このカッコを (?> ) にすると挙動が変わってしまうのでご注意下さい。

この \K を使った正規表現は秀丸の設定から直接 hmonig.dll を指定した場合には "エラー217" は出ませんが、
HmJreSelect.dll を経由させると 大文字/小文字の区別 = 無効 の場合に "エラー217" が出ます。

Onigmo の \K には #152 で報告されている不具合がありますが、今回の正規表現はその影響を受けません。
( \K の後ろに続く正規表現がゼロ幅マッチをすると次の検索開始位置が1つ進んでしまう不具合があります )
( フォーク元の oniguruma の \K にはこの不具合はありません )

(?<! ) と /i の組み合わせによる不具合は過去にもありました。 ( #92 )

@Fzok4234
Copy link
Author

For the time being, we have avoided using \K in any definition of (?<varName>) sub-expression. Because, these sub-expression call will not work properly in the atomic group (?>) like the following example.
(?<token>(?>(?:\$\g<varName>)|\g<numeric>|(\((?:\g<space>\g<token>)*+\g<space>\))))
Therefore, we are not free to use any atomic group (?>) for speedup, if the \K is mixed in with any of the definitions of (?<>) sub-expression.

@tonco-miyazawa
Copy link

tonco-miyazawa commented May 20, 2022

\$\g<varName>

\g<varName> をこのように使うことは想定していませんでした。
\g<varName> に含まれる \K がマッチした場合、それ以前にマッチした文字列が捨てられてしまいます。
そのため、"$" はマッチした文字列から除かれてしまう可能性があります。

また、 \K の直前にある "." にマッチすることが必要なため、"$" と変数名の間に、名前とは
無関係な1文字へのマッチが必要になります。 このため、あなたがマッチさせたいと思う変数名にマッチ出来ません。

\g<token> の再帰的な処理の中で、 \g<varName> の中の \K がマッチした場合も同様です。
これは破壊的な動作になるでしょう。

あなたの書き込みの中に \g<> が登場した時、私はこの使い方に気付くべきでした、すみません。

従って、最善の対策は私が最初のコメントに書いた対策になるでしょう。

対策はもう1つあり、Hidemaru のDLLの設定から hmonig.dll を直接指定して使う方法があります。
そして (?iu) を使わずに (?u) を使い、検索ダイアログから 大文字/小文字の区別 = 無効 を選びます。

ただし、このときの動作はあなたが期待する動作になるか、そうでないか、それは私には分かりません。


The point of this issue

// This is OK.

(?ui)
(?<!
	[\p{Lu}]
)

// But, This is an error.

(?ui)
(?<name>
	[\p{Lu}]
){0}
(?<!
	\g<name>
)

It violates the character limit of (?<! ) when going through \g<>.
This issue is not in oniguruma.

Workaround (1)

// Apply option "(?-i)"

(?ui)
(?<name>
	(?-i)
	[\p{Lu}\p{Ll}]
	(?i)
){0}
(?<!
	\g<name>
)

Workaround (2)

// Don't use \g<>.

(?ui)
(?<!
	[\p{Lu}]
)

Another pattern that violates the character limit of (?<! )

// This is an error.

(?ui)
(?<!
	[\p{Lu}\p{Ll}\p{Lt}]
|
	[\p{Nd}]
)

// The above workaround.

(?ui)
(?<!
	[\p{Lu}\p{Ll}\p{Lt}]
)
(?<!
	[\p{Nd}]
)

or

(?ui)
(?<!
	[\p{Lu}\p{Ll}\p{Lt}\p{Nd}]
)

Related links

"ss" in look-behind raises syntax error #92
ſ(U+017F) and K(U+212A) should not be case-insensitive equivalent to S and K #141

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants