Class | regex |
In: |
regex.f90
|
Subroutine : | |
pattern : | character(len = *), intent(in) |
text : | character(len = *), intent(in) |
start : | integer, intent(out) |
length : | integer, intent(out) |
pattern には正規表現を与えます。 text には正規表現によって探査したい文字列を与えます。
pattern が text にマッチした場合、 start には文字列の何文字目からマッチしたのかを示す数値 (正の整数) が返ります。 length には何文字分マッチしたのかを示す数値 (正の整数) が返ります。
マッチしない場合、 length == -1, start == 0 となります。
program regex_test use regex, only: match use dc_types, only: TOKEN implicit none integer:: start, length character(TOKEN) :: pattern, text continue pattern = "->" text = "time->0.0,x->hoge" call match(trim(pattern), trim(text), start, length) call formatted_print pattern = "^##+" text = "####### hoge" call match(trim(pattern), trim(text), start, length) call formatted_print pattern = "@+$" text = "# hoge @@@" call match(trim(pattern), trim(text), start, length) call formatted_print contains subroutine formatted_print use dc_string, only: Printf call Printf(fmt='pattern= %c : text= %c : start= %d : length= %d', & & c1=trim(pattern), c2=trim(text), i=(/start, length/)) end subroutine formatted_print end program regex_test
このプログラムを実行することで以下の出力が得られるはずです。
pattern= -> : text= time->0.0,x->hoge : start= 5 : length= 2 pattern= ^##+ : text= ####### hoge : start= 1 : length= 7 pattern= @+$ : text= # hoge @@@ : start= 8 : length= 3
subroutine match(pattern, text, start, length) ! ! _pattern_ には正規表現を与えます。 ! _text_ には正規表現によって探査したい文字列を与えます。 ! ! _pattern_ が _text_ にマッチした場合、 ! _start_ には文字列の何文字目からマッチしたのかを示す数値 (正の整数) ! が返ります。 ! _length_ には何文字分マッチしたのかを示す数値 (正の整数) ! が返ります。 ! ! マッチしない場合、 length == -1, start == 0 となります。 ! ! !=== 例 ! ! program regex_test ! use regex, only: match ! use dc_types, only: TOKEN ! implicit none ! ! integer:: start, length ! character(TOKEN) :: pattern, text ! continue ! pattern = "->" ! text = "time->0.0,x->hoge" ! call match(trim(pattern), trim(text), start, length) ! call formatted_print ! ! pattern = "^##+" ! text = "####### hoge" ! call match(trim(pattern), trim(text), start, length) ! call formatted_print ! ! pattern = "@+$" ! text = "# hoge @@@" ! call match(trim(pattern), trim(text), start, length) ! call formatted_print ! ! contains ! subroutine formatted_print ! use dc_string, only: Printf ! call Printf(fmt='pattern= %c : text= %c : start= %d : length= %d', & ! & c1=trim(pattern), c2=trim(text), i=(/start, length/)) ! end subroutine formatted_print ! ! end program regex_test ! ! このプログラムを実行することで以下の出力が得られるはずです。 ! ! pattern= -> : text= time->0.0,x->hoge : start= 5 : length= 2 ! pattern= ^##+ : text= ####### hoge : start= 1 : length= 7 ! pattern= @+$ : text= # hoge @@@ : start= 8 : length= 3 ! implicit none character(len = *), intent(in):: pattern, text integer, intent(out):: start, length integer, allocatable:: ipattern(:) integer:: text_length continue ! 空 pattern は空文字列に適合 if (len(pattern) <= 0) then length = 0 start = 1 return endif ! メタキャラクタの認識 allocate(ipattern(len(pattern) + 2)) call preprocess_pattern(pattern, ipattern) ! 頭寄せ指定のある場合 if (ipattern(1) == SYM_HEADFIX) then start = 1 call match_here(ipattern(2: ), text, length) if (length < 0) goto 995 goto 999 endif ! 最左原理 text_length = len(text) do, start = 1, text_length + 1 call match_here(ipattern, text(start:text_length), length) if (length >= 0) goto 999 end do ! みつからない場合 995 continue start = 0 length = -1 999 continue deallocate(ipattern) end subroutine match