74663


Boost.Regex、Onigmoの正規表現についてです。

正規表現は、左から右側に向かって数えるパターンは一般的ですが、逆の文末から文字数を数えるパターンです。

置換で句読点をたくさんいれたのですが、なかには、以下のように文末の直前でも句読点がはいることになります。

事例

[code]

    ということで、ある。
    
[/code]

句読点は文中にはあったほうがいいのもありますが、一律に置換するとこのようにもなりますので、あまりにも文末に近いところにつくとヘンになります。

この課題として、文末の "。" から、右から左側に10文字以内の "、" をマッチさせて消してしまうという正規表現です。

例文

[code]

    自動車業界は、自動運転の方向で、法整備が進んでいるので、ある。
    
[/code]

置換後

[code]

    自動車業界は、自動運転の方向で、法整備が進んでいるのである。
    
[/code]

10文字以内のものは一括でマッチさせたいですが、例外として、以下のパターンは除くと言う条件にしたいです。

接続が "は、" になっているところです。

事例

[code]

    オーストラリア大陸は、続く。
    
[/code]

置換後 影響しない

[code]

    オーストラリア大陸は、続く。
    
[/code]

このように文末の "。" の直前でも "は、" は例外とするというパターンです。。


CC BY-SA 4.0
2021-03-14T01:34:16.900
74661
2021-03-15T00:40:53.607
2021-03-15T00:40:53.607
43999
43999
question
正規表現
文末の右から左側への文字数を数えて、文字をマッチさせる


自分で右から左に数える必要はありません。`{0,9}` で 0 回以上 9
回以下の量指定ができるので、これが使えます（ドキュメント：[Boost.Regex](https://www.boost.org/doc/libs/1_75_0/libs/regex/doc/html/boost_regex/syntax/perl_syntax.html#boost_regex.syntax.perl_syntax.repeats)、[Onigmo](https://github.com/k-takata/Onigmo/blob/dd8a18af5c2f2871104b1bdbf3bbb597ec9e4665/doc/RE.ja#L135)）。たとえば以下の正規表現でマッチまではできるので、よしなに置換すれば良いでしょう。

[code]

    [^は]、.{0,9}。
    
[/code]

ひとつ注意点として、句点から 10 文字以内に読点が複数個含まれる場合や、読点を削除した結果 10
文字以内に新しい読点が含まれるようになる場合があります。今回は手で置換したいだけのようなので同じ置換を何回か繰り返せば再帰的に削除していくことができますが、もし機械的に削除を行いたい場合は仕様をどうするのか考えるところからやるのが良さそうです。

追記：自明だと思って書いていませんでしたが、句点だけを置換したい場合 `()` でグループ化して参照するようにすれば良いです。


CC BY-SA 4.0
2021-03-14T03:05:49.757
74662
2021-03-14T22:25:10.337
2021-03-14T22:25:10.337
19110
19110
74661
answer


一部の正規表現には先読み（`(?=...)`と`(?!...)`）という機能があります。先に読み進めることはないものの、直後に何が続いているか／続いていないかの判定が行えます。これを使うと

[code]

    、(?=.{0,9}。)
    
[/code]

とでき、「直後の10文字以内に`。`が現れる」という条件を満たす`、`を見つけることができます。

更に後読み（`(?<=...)`と`(?<!...)`）という機能で、直前に何が続いていた／続いていなかったかも判定できます。これを使うと

[code]

    (?<!は)、(?=.{0,9}。)
    
[/code]

とでき、「直前に`は`が現れず直後の10文字以内に`。`が現れる」という条件を満たす`、`を探すことができます。

Boost.RegexのPerl構文とOnigmoはこれらの機能に対応していると思います。

* * *

> 正規表現は、左から右側に向かって数えるパターンは一般的ですが、逆の文末から文字数を数えるパターンです。

数える方向を気にされているようですが、右から数えようが左から数えようが文字数に違いはありません。

また置換について触れられていますが、正規表現はあくまで条件を満たす文字列にマッチさせるものです。どのように置換したいかはあまり関係ありません。もちろん置換方法によっては別の文字列をマッチさせた方が効率的な場合もありますが。

今回でいうと、nekketsuuuさんも指摘されていますが、置換によって文字列が短くなり、新たに条件を満たす`、`が現れることがありますが、正規表現としてはどのように置換されるかは把握していないためこのような条件にマッチさせることはできません。  
少し条件を変えて「`、`以外の文字が10文字以下続く`。`」という考え方も可能ですが、残念ながらこれを表すのは無理（少なくとも私はわからない）です。


CC BY-SA 4.0
2021-03-14T03:32:51.197
74663
2021-03-14T04:07:33.293
2021-03-14T04:07:33.293
4236
4236
74661
answer