tag:crieit.net,2005:https://crieit.net/tags/%E6%AD%A3%E8%A6%8F%E8%A1%A8%E7%8F%BE/feed
「正規表現」の記事 - Crieit
Crieitでタグ「正規表現」に投稿された最近の記事
2021-02-26T06:00:56+09:00
https://crieit.net/tags/%E6%AD%A3%E8%A6%8F%E8%A1%A8%E7%8F%BE/feed
tag:crieit.net,2005:PublicArticle/16701
2021-02-26T06:00:56+09:00
2021-02-26T06:00:56+09:00
https://crieit.net/posts/Ruby
正規表現エンジン(ロブ・パイクのバックトラック実装)をRubyで写経した
<p>元になっているのは『プログラミング作法』に載っている、ロブ・パイクが書いたコード(以下「ロブ・パイク版」)ですが、<a target="_blank" rel="nofollow noopener" href="https://postd.cc/build-your-own-regex/">40行以内で正規表現エンジンを構築 | POSTD</a> の方を見て書いてみました。JavaScript の方が読み慣れているのと、<a target="_blank" rel="nofollow noopener" href="https://github.com/nadrane/build-your-own-regex">リポジトリ</a>にテストコードが用意されていたためです。</p>
<pre><code class="ruby">def drop(text, n)
text.chars.drop(n).join()
end
def empty?(str)
str.nil? || str.empty?
end
def match_one(pattern_char, char)
return true if empty?(pattern_char)
return false if empty?(char)
pattern_char == "." || pattern_char == char
end
# ロブ・パイク版では match
def search(pattern, text)
if pattern[0] == "^"
match(drop(pattern, 1), text)
else
match(".*" + pattern, text)
end
end
# ロブ・パイク版では matchhere
def match(pattern, text)
return true if empty?(pattern)
return true if empty?(text) && pattern == "$"
case pattern[1]
# when "?"
# match_question(pattern, text)
when "*"
match_star(pattern, text)
else
match_one(pattern[0], text[0]) &&
match(drop(pattern, 1), drop(text, 1))
end
end
# def match_question(pattern, text)
# (
# match_one(pattern[0], text[0]) &&
# match(drop(pattern, 2), drop(text, 1))
# ) ||
# match(drop(pattern, 2), text)
# end
def match_star(pattern, text)
(
match_one(pattern[0], text[0]) &&
match(pattern, drop(text, 1))
) ||
match(drop(pattern, 2), text)
end
</code></pre>
<p>たったこれだけで正規表現の基本的な機能が実現できるのすごい&おもしろいですね。</p>
<p>ロブ・パイク版では <code>.</code> <code>^</code> <code>$</code> <code>*</code> だけをメタ文字としてサポートする最低限の実装をまず示し、演習問題で <code>?</code> などを追加する流れになっています(なので、上に貼ったコードでは <code>?</code> の部分をコメントアウトしてみました)。</p>
<hr />
<p>書籍『ビューティフルコード』では「1章 正規表現マッチャ」をブライアン・カーニハンが書いており、ロブ・パイク版について解説しています。</p>
<p>このコードが生まれた経緯について書かれていて、ここもおもしろい。</p>
<blockquote>
<p> 1998年、ロブ・パイク(Rob Pike)と私は、『プログラミング作法』(原題『The Practice of Programming』、Addison-Wesley刊)という本を執筆していました。(略)<br />
問題は、既存の正規表現パッケージはどれも大き過ぎたということでした。(略)それでは教育用に適しているとは到底言えません。<br />
そこで私はロブに、正規表現の基本的な考え方が読み取れる最小限の、ただしそれでいて有用でつまらなくないパターンが書けるようなパッケージを探そうと提案しました。コードが本の1ページに納まるようなら理想的だと思いました。<br />
ロブは自分の部屋に入って行きました。今思い返してみると、1〜2時間も経たないうちだったと思います。<br />
彼は30行のCのコードを携えて部屋から出て来ました。そのコードが、『プログラミング作法』の第9章に掲載されているものです。(略)</p>
</blockquote>
<h1 id="参考"><a href="#%E5%8F%82%E8%80%83">参考</a></h1>
<ul>
<li><a target="_blank" rel="nofollow noopener" href="https://www.oreilly.co.jp/books/9784873113630/">O'Reilly Japan - ビューティフルコード</a>
<ul>
<li>英語ですが <a target="_blank" rel="nofollow noopener" href="https://www.cs.princeton.edu/courses/archive/spr09/cos333/beautiful.html">A Regular Expression Matcher(www.cs.princeton.edu)</a> で「1章 正規表現マッチャ」と同じ内容が読めるようです。</li>
</ul></li>
<li>プログラミング作法
<ul>
<li><a target="_blank" rel="nofollow noopener" href="https://asciidwango.jp/post/155982762075">アスキードワンゴ</a></li>
<li><a target="_blank" rel="nofollow noopener" href="https://tatsu-zine.com/books/practice-of-programming">達人出版会</a></li>
</ul></li>
<li><a target="_blank" rel="nofollow noopener" href="https://gihyo.jp/book/2015/978-4-7741-7270-5">正規表現技術入門 ――最新エンジン実装と理論的背景:書籍案内|技術評論社</a>
<ul>
<li>「5.1 基本的なVM型エンジンの実装」にロブ・パイク版についての説明があります。</li>
</ul></li>
</ul>
sonota486
tag:crieit.net,2005:PublicArticle/16021
2020-08-01T03:02:13+09:00
2020-08-01T03:02:13+09:00
https://crieit.net/posts/PHP-5f245ca597498
各種小説投稿サイトのルビ記法をPHPで実現する
<p>「<a target="_blank" rel="nofollow noopener" href="https://qiita.com/8amjp/items/d7c46d9dee0da4d530ef">各種小説投稿サイトのルビ記法をJavaScriptで実現する</a>」<br />
こちらの記事を参考にPHPで関数として作ってみました。</p>
<pre><code class="php">function ruby(string $str) {
$str = preg_replace('/[||](.+?)(?|((.+?))|\((.+?)\)|《(.+?)》)/u', '<ruby>$1<rt>$2</rt></ruby>', $str);
$str = preg_replace('/(\p{Han}+)(?|((.+?))|\((.+?)\)|《(.+?)》)/u', '<ruby>$1<rt>$2</rt></ruby>', $str);
return $str;
}
</code></pre>
<p>短歌にルビを振る目的で作ったため、かなりルビが反映されやすくなっています。<br />
普通の文章にルビを振る場合は、括弧のパターンを減らしたり、括弧がそのまま残る置換を追加したり、括弧内が平仮名カタカナだけになるようにカスタムするといいでしょう。<br />
気が向いたら更新します。</p>
ウラル