2013-10-21

【テキスト】正規表現パターン作成代行サービス開始!

久しぶりに何かお客様から依頼されてモノを作りたくなったので、ちっちゃいところからやり直そうと言うことで正規表現を作成代行してみようと思います。
あまりにも複雑な正規表現パターン(たとえば、規約どおりのメールアドレスのパターンとか)じゃ無ければ作りますので、良かったらオーダーしてみてください。

→依頼ページ:正規表現についての簡単なものを作成します!

□依頼時の注意点
・料金は一つの依頼につき500円です。
・処理対象テキストデータを送ってもらいます。
 たとえばHTML、Aタグのhref属性を取得したいなら具体的なAタグのテキストを複数ください。
・処理内容の具体的な内容
 たとえば、XMLデータならどのタグの要素が欲しい、とか書いてください。

□依頼してからパターンが納品される日数
・簡単なものなら1日、比較的複雑なもので2~3日程度で納品します。
・パターン個数は基本的に1つの依頼で1つにしようと思っています。

以上です。それでは。

2013-10-05

【青空文庫】青空文庫のXMLをパースしてみた

【青空文庫】青空文庫のXMLをパースしてみた 自分の読書用に青空文庫に掲載してあるXMLをパースしてみたよ。
青空文庫のXMLは仕様通りにキッチリ書いてあるものと、そうでないものがあり、ちょっと苦労した。

以下のクラスは基本的に「大見出し」と「中見出し」で区切って配列にして返すものだけど、面倒な処理は正規表現やexplodeでばっさり切り分けたりしてます。

---
このクラスを使って小説を転載したものは、以下のサイトで読めます。
 ・多賀城[たがのき]小説投稿サイト
良かったら見てくださいませ。
---

/*
*   青空文庫XMLパーサ
*     2013/10/01
*/
class Aozora
{
  const         FROM_ENCODING = 'sjis-win';
  const         TO_ENCODING   = 'UTF-8';
  
  public        $filename;
  public        $title;
  public        $author;
  /*
    本文の階層構造
    
    大見出しがある場合
    bodies = array(
      '大見出し_01' => array( '中見出し_01' => '本文', '中見出し_02' => '本文', ... '中見出し_nn' => '本文' ),
      '大見出し_02' => array( '中見出し_01' => '本文', '中見出し_02' => '本文', ... '中見出し_nn' => '本文' ),
      '大見出し_03' => array( '中見出し_01' => '本文', '中見出し_02' => '本文', ... '中見出し_nn' => '本文' ),
              ...
      '大見出し_nn' => array( '中見出し_01' => '本文', '中見出し_02' => '本文', ... '中見出し_nn' => '本文' ) );
      
    大見出しが無い場合
    bodies = array( '中見出し_01' => '本文', '中見出し_02' => '本文', ... '中見出し_nn' => '本文' );
  */
  public        $bodies;
  public        $infomation;          // 小説情報
  public        $notes;               // 注
  public        $is_omidasi;
  public        $is_tyumidasi;
  
  private       $raw_text;
  private       $main_text;
  private       $biblio;
  
  public function __construct( $filename )
  {
    $this->filename = $filename;
    $this->raw_text = file_get_contents( $this->filename );
    $this->raw_text = mb_convert_encoding( $this->raw_text, self::TO_ENCODING, self::FROM_ENCODING );
    $this->bodies = array();
  }
  
  public function get_title()
  {
    return sprintf( '%s (作者:%s)', $this->title, $this->author );
  }
  
  public function get_bodies()
  {
    return $this->bodies;
  }
  
  /**
    XMLパース本体
  */
  public function parse()
  {
    // 改行を全て消す
    $this->raw_text = preg_replace( '#[\n\r]+#i', '', $this->raw_text );
    $this->raw_text = preg_replace( '#[\s]+#i', ' ', $this->raw_text );
    
    // タイトルと著者を取得する
    $ret = preg_match( '#

(.*?)

#i', $this->raw_text, $temp_text ); $this->title = $this->replace_imgtag( $temp_text[ 1 ] ); $this->title = trim( $this->title ); $ret = preg_match( '#

(.*?)

#i', $this->raw_text, $temp_text ); $this->author = $this->replace_imgtag( $temp_text[ 1 ] ); $this->author = trim( $this->author ); // 付加情報を取得する $ret = preg_match( '#
(.*?)
#i', $this->raw_text, $temp_text ); $this->infomation = $this->remove_htmltag( $temp_text[ 1 ] ); $this->infomation = $this->add_return( $this->infomation ); $this->infomation = trim( $this->infomation ); // 本文を全て取得する $ret = preg_match( '#
(.*)
#i', $this->raw_text, $temp_text ); $this->main_text = trim( $temp_text[ 1 ] ); // 大見出しから切り出し $this->parse_omidasi(); } /* 大見出しがある場合の本文切り出し */ private function parse_omidasi() { if( $this->is_omidasi( $this->main_text ) ) { // 大見出しがある場合 $temp_text = explode( '

', $this->main_text ); foreach( $temp_text AS $temp ) { if( trim( $temp ) == "" ) { continue; } if( !$this->is_omidasi( $temp ) ) { continue; } $ret = preg_match( '#(.*?)

(.*)$#', $temp, $temp_omidasi ); $omidasi = $this->remove_htmltag( $temp_omidasi[ 1 ] ); $omidasi = $this->replace_imgtag( $omidasi ); $omidasi = trim( $omidasi ); $this->bodies[ $omidasi ] = $this->parse_tyumidasi( $temp_omidasi[ 2 ] ); } } else { // 大見出しがない場合 $this->bodies[] = $this->parse_tyumidasi( $this->main_text ); } } /* 中見出しから本文切り出し @param $html 大見出し1つ分のテキスト または 本文全体のテキスト */ private function parse_tyumidasi( $html ) { $tyumidasi_array = array(); if( $this->is_tyumidasi( $html ) ) { $temp_text = explode( '

', $html ); foreach( $temp_text AS $idx => $temp ) { if( trim( $temp ) == "" ) { continue; } if( !$this->is_tyumidasi( $temp ) ) { continue; } $ret = preg_match( '#(.*?)

(.*)$#', $temp, $temp_tyumidasi ); $tyumidasi = $this->remove_htmltag( $temp_tyumidasi[ 1 ] ); $tyumidasi = $this->replace_imgtag( $tyumidasi ); $tyumidasi = trim( $tyumidasi ); $tyumidasi_array[ $tyumidasi ] = $this->remove_htmltag( $temp_tyumidasi[ 2 ] ); $tyumidasi_array[ $tyumidasi ] = $this->replace_imgtag( $tyumidasi_array[ $tyumidasi ] ); $tyumidasi_array[ $tyumidasi ] = $this->add_return( $tyumidasi_array[ $tyumidasi ] ); } } else { $tyumidasi_array[ 1 ] = $this->remove_htmltag( $html ); $tyumidasi_array[ 1 ] = $this->replace_imgtag( $tyumidasi_array[ 1 ] ); $tyumidasi_array[ 1 ] = $this->add_return( $tyumidasi_array[ 1 ] ); } return $tyumidasi_array; } /* 大見出しがあるかどうか */ private function is_omidasi( $html ) { $ret = substr_count( $html, '' ); if( $ret > 0 ) { $this->is_omidasi = true; } else { $this->is_omidasi = false; } return $this->is_omidasi; } /* 中見出しがあるかどうか */ private function is_tyumidasi( $html ) { $ret = substr_count( $html, '' ); if( $ret > 0 ) { $this->is_tyumidasi = true; } else { $this->is_tyumidasi = false; } return $this->is_tyumidasi; } /* 余分なHTMLタグを除去する */ private function remove_htmltag( $text ) { return preg_replace( '#<(?:|/)(?:em|div|span|a|h3|h4|hr)[^>]*>#', '', $text ); } /* 画像タグを置き換える */ private function replace_imgtag( $text ) { return preg_replace( '#]+>#', "$1", $text ); } /* * 改行を元に戻す */ private function add_return( $text ) { return preg_replace( '#]+>#', "\r\n", $text ); } }


以上です。

ZenBack

WebMoney ぷちカンパ