PHP


php_mecabで複合名詞を取り出すサンプルコード

単純に名詞が連続したら一つにまとめて取り出しています

サンプルコード
-----------------------------------------------------------------------------
parseToNode($txt); $node; $node=$node->getNext()){
if($node->getStat() != 2 && $node->getStat() != 3 && mb_strpos($node->getFeature(), '名詞', NULL, 'utf-8')===0){
$word .= $node->getSurface();
} else if ($word != '') {
array_push($meisi, $word); //渡された変数をarrayの最後に加える
$word = '';
}
}

//最後が名詞で終わった場合用の追加処理。
if ($word != '') array_push($meisi, $word);
//名詞の重複削除
$meisi = array_unique($meisi);

print("

");
print_r($meisi);
print("

");
?>
-----------------------------------------------------------------------------

php_mecabの使い方、サンプルコード

php_mecabの簡単なサンプルコード集です。

単語ごとに区切るサンプルコード
-------------------------------------------------------------------------
<?php
$str = "MeCabを使って文章を単語ごとに区切ります。";
$result = mecab_split($str); //区切って配列に入れる。単語で分割。
foreach ($result AS $value) {
echo $value ."<br>";
}
?>
-------------------------------------------------------------------------

結果
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
MeCab

使っ

文章

単語
ごと

区切り
ます
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

形態素解析を行って結果を表示するサンプルコード
-----------------------------------------------------------------------
<?php
$t = new MeCab_Tagger();
$str = 'PHPのMeCabエクステンションで形態素解析を行ってみました。';
$kekka = $t->parse($str); //解析して結果を返す。
print("<pre>");
echo $kekka;
print("</pre>");
}
?>
-----------------------------------------------------------------------

結果
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
PHP 名詞,固有名詞,組織,*,*,*,*
の 助詞,連体化,*,*,*,*,の,ノ,ノ
MeCab 名詞,一般,*,*,*,*,*
エクステンション 名詞,一般,*,*,*,*,*
で 助詞,格助詞,一般,*,*,*,で,デ,デ
形態素 名詞,一般,*,*,*,*,形態素,ケイタイソ,ケイタイソ
解析 名詞,サ変接続,*,*,*,*,解析,カイセキ,カイセキ
を 助詞,格助詞,一般,*,*,*,を,ヲ,ヲ
行っ 動詞,自立,*,*,五段・ワ行促音便,連用タ接続,行う,オコナッ,オコナッ
て 助詞,接続助詞,*,*,*,*,て,テ,テ
み 動詞,非自立,*,*,一段,連用形,みる,ミ,ミ
まし 助動詞,*,*,*,特殊・マス,連用形,ます,マシ,マシ
た 助動詞,*,*,*,特殊・タ,基本形,た,タ,タ
。 記号,句点,*,*,*,*,。,。,。
EOS
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

形態素の詳細情報を配列で取得するサンプルコード
-----------------------------------------------------------------------
<?php
$text = "親と健康は、失って初めてそのありがたみがわかるもの、なんてよくいわれる。";
$mecab = new Mecab();

$nodes = $mecab->parseToNode($text); //形態素の詳細情報を配列で取得
foreach ($nodes as $node) {
echo $node->surface . "<br>"; //表層形(単語そのもの)を取得

echo $node->feature . "<br>"; //形態素情報を取得

echo $node->cost . "<br>"; //形態素までのコスト

echo $node->posid . "<br><br>"; //ステータス番号を取得
}
?>
-----------------------------------------------------------------------

//バージョンを出力
-----------------------------------------------------------------------
echo mecab_version();
-----------------------------------------------------------------------

//読み方だけ表示
-----------------------------------------------------------------------
<?php
$text = "親と健康は、失って初めてそのありがたみがわかるもの、なんてよくいわれる。";
$mecab = new Mecab();

$nodes = $mecab->parseToNode($text); //形態素の詳細情報を配列で取得

$kana = "";
foreach ($nodes as $node) {

$surface = $node->surface; //表層面。単語だけ。
$feature = $node->feature; //形態素情報を取得

//ひらがなかカタカナならそのまま
if(preg_match("/^[ぁ-ゞァ-ヾー]+$/u",$surface)) {

$kana .= $surface;

//ひらがなでもカタカナでもないなら読みを取り出す
} else {
//8番目の情報だけ残す。
$kana .= preg_replace('/^.*?,.*?,.*?,.*?,.*?,.*?,.*?,(.*?),.*$/su','$1', $feature);
//$kana .= preg_split('/,/u',$feature)[7]; // ←こっちでも可。
} //if
//BOS/EOSの場所につく「*」を削除。
$kana = preg_replace('/^\*/u','',$kana);
$kana = preg_replace('/\*$/u','',$kana);
}

echo $kana;
?>
-----------------------------------------------------------------------

さくら共有サーバー、php_mecabのインストール方法

さくら共有サーバー、php_mecabのインストール方法

前提として、mecab の辞書にアクセスする必要があるので辞書をローカルフォルダ以下にインストールしておく必要があ(さくらに最初から入っている辞書を使うこともできるが、htmlファイルが UTF-8 の場合、デフォルトの辞書が EUC なので文字化けしてしまう)。
さくら共有サーバー、UTF-8の辞書でmecabを使う方法 ←この作業を済ませておく

1.ファイルを解凍してビルド
///////////////////////////////////////////////////
tar xvfz php-mecab-0.5.0.tgz ←解凍

cd php-mecab-0.5.0 ←ディレクトリ移動

phpize ←拡張モジュールをビルド(ソースファイルから実行可能なファイルを作成。configureファイルができる)
※-ize(アイズ)・・・~化する。~で扱う。

※エックスサーバーでは phpize は使えないので php_mecab はインストールできない。yum や rpm コマンドが使えないので phpize の追加もできない。どうしても phpize が使えない環境で PHP + mecab を実行したいなら PHP の EXEC 関数でコマンドラインを操作してすることならできそう?
///////////////////////////////////////////////////

2.「configure」を実行
///////////////////////////////////////////////////
./configure --with-mecab=/usr/local/bin/mecab-config --with-php-config=/usr/local/php/5.3.27/bin/php-config
///////////////////////////////////////////////////
php-configのバージョンは必ずあわせる。現在使用しているphpのバージョンをphpinfoで確認。今回は「5.3.27」。指定しなくてデフォルトのバージョンが呼び出されるとうまくいかない。phpのバージョンはターミナルから「php -v」でも調べられるが出てきたバージョンのフォルダ名がない場合がある(php -v で「5.45」と出たが存在するフォルダは「5.4」だった)。使用しているphp のバージョンはサーバーコントロールにログインして調べるといい。
mecab-configの場所は「which mecab-config」で特定できる。自前の mecab をインストールしている場合はそちらのパスを指定する。

3.コンパイルとインストール
///////////////////////////////////////////////////
make ←コンパイル
make install ← インストール
///////////////////////////////////////////////////

インストールするとエラーメッセージが出た
----------------------------------------------------------------------
Installing shared extensions: /usr/local/php/5.3.27/lib/php/extensions/no-debug-non-zts-20090626/
cp: /usr/local/php/5.3.27/lib/php/extensions/no-debug-non-zts-20090626/#INST@99219#: Permission denied
----------------------------------------------------------------------
権限のないところにインストールを試みているよう。
ローカルフォルダにインストールするように、Makefileをいじる。(make実行後に作成されるファイル)

Makefileの変更箇所
----------------------------------------------------------------------
#EXTENSION_DIR = /usr/local/php-5.x.x/lib/php/extensions/no-debug-non-zts-20060613 ←コメントアウト
EXTENSION_DIR = $(HOME)/local/lib/php/extensions/no-debug-non-zts-20060613 ←追記
※「20060613」とかフォルダ名は合わせるといい。
----------------------------------------------------------------------

再びmake installすると無事にインストールが完了するはず。

4.続いて、PHPの起動時に読み込まれる拡張モジュールを設置するディレクトリの設定

PHP.iniに拡張モジュールの置き場を記述する

PHP.iniに記述(追記)する内容
----------------------------------------------------------------------
extension_dir="/home/username/local/php-mecab-0.5.0/modules"
extension=mecab.so
----------------------------------------------------------------------
※拡張子 so は shared object の略。UNIX系OSの共有ライブラリのファイル形式。

最初、こう書いたら動かなかくてハマった。
----------------------------------------------------------------------
extension_dir="/home/username/local/lib/php/extensions"
extension=mecab.so
----------------------------------------------------------------------

作業時に出力されたメッセージを見てとりあえず動くところまで持ってこれた。
----------------------------------------------------------------------
Libraries have been installed in:
/home/sunsdoor/local/php-mecab-0.5.0/modules

If you ever happen to want to link against installed libraries
in a given directory, LIBDIR, you must either use libtool, and
specify the full pathname of the library, or use the `-LLIBDIR'
flag during linking and do at least one of the following:
- add LIBDIR to the `LD_LIBRARY_PATH' environment variable
during execution
- add LIBDIR to the `LD_RUN_PATH' environment variable
during linking
- use the `-Wl,--rpath -Wl,LIBDIR' linker flag

See any operating system documentation about shared libraries for
more information, such as the ld(1) and ld.so(8) manual pages.
----------------------------------------------------------------------

UTF-8の辞書を使いたいのでphp.iniに追記
----------------------------------------------------------------------
mecab.default_dicdir=/path/ ←辞書
mecab.default_userdic=/path/ ←ユーザ辞書
----------------------------------------------------------------------
※UTF-8 の辞書を使う場合は phpファイルの保存形式やメタタグ(headタグ内)の文字コードも UTF-8 に揃える必要がある。

自分の環境だといずれか(dicrcとかsys.dicがあるフォルダ)
----------------------------------------------------------------------
mecab.default_dicdir="/home/username/local/mecab-dic/ipadic-utf8"
mecab.default_dicdir="/home/username/local/lib/mecab/dic/ipadic"
----------------------------------------------------------------------

うまくいっていたらphpinfoにmecabの項目が表示されている。

さくら共有サーバー、UTF-8の辞書でmecabを使う方法

(mecab本体のインストールはこちら。ただしさくら共用にはあらかじめ mecab がインストールされているので不要。php-mecab を使用する場合も不要。)
さくら共用サーバーにmecabをインストールする

さくらインターネットにはmecabが最初からインストールされている。
しかし辞書の文字コードがEUC-JPなので自分の環境では文字化けしてしまう。

これを解決するためには、UTF-8の辞書をインストールする。以下、その方法。

まず、インストール先を決める。さくら共有サーバーでインストール権限があるのは、ホームディレクトリ以下。
自分でコンパイルしたアプリケーションをインストールする場所は、ホームディレクトリ以下のlocalフォルダが一般的のよう。

0.インストールするディレクトリを作成しておく
------------------------------------------------
/home/username/local/mecab-dic/ipadic-utf8 ←localディレクトリはないので新規作成
------------------------------------------------

1.辞書のダウンロードと解凍を行う
------------------------------------------------
(ポデローサで打ったコマンド)
cd local ←ローカルディレクトリに移動(ダウンロード先)

wget http://sourceforge.net/projects/mecab/files/mecab-ipadic/2.7.0-20070801/mecab-ipadic-2.7.0-20070801.tar.gz ← 辞書をダウンロード

tar xvzf mecab-ipadic-2.7.0-20070801.tar.gz ←解凍
------------------------------------------------

2.「configure」の実行

2-1
------------------------------------------------
cd mecab-ipadic-2.7.0-20070801 ←configureファイルのあるディレクトリに移動
------------------------------------------------

2-2
------------------------------------------------
自前のmecabがある場合
./configure --with-charset=utf8
※「/home/username/local/lib/mecab/dic/」以下に ipadic フォルダがインストール先される

インストール先としてipadic-utf8というフォルダが作ってある場合
./configure --with-charset=utf8 --with-dicdir=~/local/mecab-dic/ipadic-utf8 ←実行。
------------------------------------------------
※インストール先を、今後辞書を追加する可能性も考慮し「~/local/mecab-dic/ipadic-utf8」にする場合、フォルダはあらかじめ作っておく必要がある。
ホームディレクトリ以下に自前のmecabをインストールしている場合「--with-dicdir=~/local/mecab-dic/ipadic-utf8」を書くとmake install時にエラーになった。その場合は、インストールは指定しないことでやり過ごせる。

※「configure」というシェルスクリプトを実行することでMakefileが作成される。Makefileは、ソースファイルをコンパイルする前にインストール対象となるシステム特有の機能/情報をチェックし、チェック状況を記述したファイル。

以下の2ファイルは元々ある
------------------------------------------------
Makefile.in
Makefile.am
------------------------------------------------

configureを実行すると3つファイル増える
------------------------------------------------
config.log
config.status
Makefile
------------------------------------------------

3.インストールの実行
------------------------------------------------
make ←「configure」の実施で作られた「Makefile」を元にコンパイルを実行
make install ← インストールを実行
------------------------------------------------

4.動作テスト
------------------------------------------------
mecab -d ~/local/mecab-dic/ipadic-utf8 ←辞書を指定
これはテストです
------------------------------------------------

結果
------------------------------------------------
これ 名詞,代名詞,一般,*,*,*,これ,コレ,コレ
は 助詞,係助詞,*,*,*,*,は,ハ,ワ
テスト 名詞,サ変接続,*,*,*,*,テスト,テスト,テスト
です 助動詞,*,*,*,特殊・デス,基本形,です,デス,デス
------------------------------------------------

↓ターミナル経由でmecabを実行して解析結果が空欄だった場合、ターミナルの文字コードが違う可能性が考えられる。
自分の場合、辞書をUTF-8にしてもターミナルの文字列はEUC-JPに設定する必要があった。
------------------------------------------------
これはテストです
これは ̾,,*,*,*,*,*
テスト ̾,,*,*,*,*,*
です ̾,,*,*,*,*,*
------------------------------------------------

mecab -d ~/local/mecab-dic/ipadic-utf8 -D
これで辞書情報が確認できる。charsetがutf8であればOK

問題なく動くことを確認する。

mecabを終了するときは、「Ctrl + D」

本来ここまでの作業でUTF-8化した辞書がインストールできているはず。が、別アカウントのサクラサーバーで同じように辞書をインストールするとうまくいかない。手順どおり辞書のインストールを行うと滞りなく進むのだが、いざmecabで形態素解析を行うと、UTF-8を認識しない。EUC-JPで辞書がインストールされているようだ。
いろいろ調べたが根本的理由はわからず。バグかな?
下記の方法を行えばとりあえずUFT-8でmecabを動かせるようになります。

辞書インストール時、辞書のフォルダを解凍した後(configure実行の前)に2つのことを行う。

1.辞書フォルダ内の「csv」と「def」の拡張子のファイルをUTF-8に変換して上書きする。

テキストファイルで保存しなおしてもいいし、コマンドラインなら次のように打つ(cshellの場合)。

//まず、今の文字コードを確認
------------------------------------------------
cd mecab-ipadic-2.7.0-20070801 ← 辞書フォルダ内に移動

nkf -g Noun.csv ← とりあえずひとつのファイルの文字コードを確認してみる。gオプションは文字コードを出力。この時点ではEUC-JPが返るはず。
------------------------------------------------

//「csv」のファイルをUTF-8に変更
------------------------------------------------
foreach f ( *csv ) ← フォルダ内のcsvファイルに対して繰り返す(fは何の文字でもいい)

nkf -w --overwrite $f ← UTF-8に変更して上書き

end ← 「foreach?」と出てるはずなので終える
------------------------------------------------

//UTFになっていることを確認
------------------
foreach f ( *csv )
nkf -g $f
end
------------------

//「def」も同じようにUTF-8に変更する
------------------------------------------------
foreach f ( *def )

nkf -w --overwrite $f ← UTF-8に変更して上書き

end ← 「foreach?」と出てるはずなので終える
------------------------------------------------

2.dicrcファイルを書き換える

dicrcファイルは辞書フォルダ内にある
------------------------------------------------
config-charset = EUC-JP ← 書き換え前

 ↓↓↓

config-charset = UTF-8 ← 書き換え後
------------------------------------------------

この後は、configure → make → make install の順でインストールを済ませばいい。

【PHP】ある文字列を含む行だけを削除する正規表現

ある文字列を含む行だけを削除する正規表現の覚書

次のようなテキストの場合
--------------------------------------

ここは残す行
ここは削除する行
ここは削除する行
ここは残す行

--------------------------------------

「削除する」というワードが含まれている行をなくしたいので、正規表現は次のようになる

//行頭から改行コードまでを空文字に置き換える
preg_replace('/^.*削除する.*[\r\n]/u','',$honbun);

これではうまくいかない場合がある。二行目以降の^がマッチしないケース。
次の書き方ならうまくいく。

preg_replace('/^.*削除する.*$/um','',$honbun);

ポイントは、修飾子m。マルチラインモードにすることで、文章途中の^や$がマッチして期待した動作になる。

【PHP】if(0)で複数行のコメントアウトする

phpで複数行をコメントアウトする場合/*~*/で囲むのが一般的。

/*
aaa
bbb
*/

しかし/*~*/が入れ子になっていたり、PHPとHTMLが交じって複数行のコメントアウトが簡単にできない場合は次のように書くといい。

<?php if(0) { ?>

0はfalseを意味するので実行されない

<?php } ?>

コメントアウトした箇所を再び実行したい場合は「1」に書き換えるだけでいい。

<?php if(1) { ?>

1はtureを意味するので実行される

<?php } ?>

【PHP】クエスチョン(?)がある演算子は三項演算子

サンプルコードにクエスチョン(?)を使った演算子らしいものを発見。
WEBで調べるのに少し手間取ったのでメモ。

三項演算子という。3つの項目を使用する唯一の演算子らしい。

---------------------------------------------------------
書式:

[条件式] ? [真の場合] : [偽の場合]
//条件式を評価し、TRUEであれば[真の場合]、FALSEであれば[偽の場合]を返す
---------------------------------------------------------

---------------------------------------------------------
サンプルコード:

$_SESSION["category"] = isset($_POST["category"]) ? $_POST["category"] : "";
//POSTの値があればPOSTの値を、なければ空文字をSESSIONに格納する
---------------------------------------------------------

【PHP】変数名に変数を使う方法

変数名に変数を使うときは、{}を用いて変数名を明示すること。

こんな感じ。

$variable1 = name;

//{}を使ってどこまでが変数名か示す
${'variable2' . $variable1} = "パイナップル";

echo variable2name; //出力結果:パイナップル

PHPでファイルをダウンロードする方法

PHPでファイルをダウンロードするサンプルコードです。
例として、mp3ファイルをダウンロードします

ケース1 サーバーにダウンロードする

------------------------------------------

<?php

// ダウンロード元のファイルパス(絶対パス、ファイル名まで含む)を指定する
$url = 'http://example.com/voice/voice.mp3';

$data = file_get_contents($url);

file_put_contents('./download/hozon.mp3',$data); //ファイルの保存先

?>

------------------------------------------

ケース2 PCにダウンロードする

------------------------------------------

<?php

// ダウンロード元のファイルパス(絶対パス、ファイル名まで含む)を指定する
$fullpath = 'http://example.com/voice/voice.mp3';

// 保存時のファイル名を設定
$filename = 'hozon.mp3';

// HTTPヘッダ送信。ローカルPCに保存するためのダイアログが出る。
header("Content-type: audio/mpeg"); //mp3の場合。ファイルの種類によって適宜変更
header("Content-Disposition: attachment; filename=$filename");
// ファイルを読み込んで出力します。
readfile($fullpath);
?>

------------------------------------------

【PHP】正規表現で置換できない。ereg_replaceとpreg_replaceの記述の違い。

マニュアルどおりやった(つもりだった)んだけどなぜか正規表現の置換がうまく行われない。

記述したのはこれ↓

--------------------------------------------------------------
<?php
$moji ="123456789";
$moji = ereg_replace("/^123/", "aaa",$moji);

echo $moji;
?>
--------------------------------------------------------------

$mojiから先頭の「123」を「aaa」に置き換えるというもの。
期待した結果は「aaa456789」なんだけど、実際の結果は「123456789」。変化無し。マッチしていない。

でいろいろ試行錯誤した結果、単純なミスに気付く。

PHPで正規表現を用いた置換を行う場合は、次の二つの関数がある。

・ereg_replace
・preg_replace

どちらも同じ仕事をするので記述にも違いがないと勝手に思っていたが、そうでないと判明。

正しい記述例
・ereg_replace("パターン", "置換文字",置換前の文字列);
・preg_replace("/パターン/", "置換文字",置換前の文字列);

つまりpreg_replaceの第一引数はパターンを//で囲む必要があるが、ereg_replaceは//で囲む必要がない。

なので最初の失敗は//を取り除くことで解決する

ereg_replace("^123", "aaa",$moji);

出力結果 aaa456789

ただしereg_replaceは将来的になくなる関数らしいので、今後はpreg_replaceを使っていく。

4 / 512345