takafumi blog

日々の勉強メモ

【PHP】 正規表現のエスケープ

環境   CentOS 7.0  PHP 7.0.1

php正規表現(preg系)のエスケープシーケンスの書き方について調べた。


以下のような正規表現がある。

$text = 'abc/def';

preg_match('/abc\\/def/', $text); # (a)
preg_match('/abc\/def/', $text);  # (b)

さて(a)と(b)、どっちが正しいか?

答えはどっちでもOK。

とはいえ(1)はうまく評価されるが、間違った書き方だと思う。

PHPのマニュアルに、

PHP: エスケープシーケンス - Manual
注意:

シングルクォートあるいはダブルクォートで囲まれた PHP の 文字列 の中では、バックスラッシュは特別な意味を表します。 そのため、正規表現 \ を使用して \ とマッチさせたい場合は PHP のコード内では "\\" あるいは '\\' と記述する必要があります。

とある。 つまり

1.PHPの文字列として評価

2.正規表現エンジンでパターンを評価

とされるからバックスラッシュ自体を評価するときは、重ねましょうと言う話のはず。


(a)のように書く人は、以下のように判断していると思われる。

1.PHPの文字列として評価

/abc\\/def/ => /abc\/def/

2.正規表現エンジンでパターンを評価

abc\/def => abc/def

確かに正しく動く。
だが、そもそも正規表現エンジン内では、/(スラッシュ)はエスケープの必要はない。

なので、なので本来は(b)のパターンでOKで問題ない。


ではバックスラッシュは?

もとのPHPが以下だとする。

$text = '\\';
preg_match('/\\/', $text);   # (c)
preg_match('/\\\/', $text);  # (d)
preg_match('/\\\\/', $text); # (e)

これだと(c)はエラーに、(d),(e)はマッチする。

(c)がエラーになるのは

1.で評価された結果、/\/となる。

しかし2.で評価されるときに、\しか渡ってこない。
そのため正規表現エンジンに正常に評価されず、エラーになる。


(e)は
1.で/\\/と変換され、2.で正規表現エンジンんい\\が渡される。 なので正常に評価される。


では(d)は?
実はこれが良くわからない。
PHPの評価順のせいか正常に評価される。
が、普通に考えれば、1.の段階で3つ目の\がスラッシュにかかりそうなもの。 しかし、正常に評価される。PHPの評価順のせいなのか?

とはいえPHPマニュアルにも書いてないので、イレギュラーな方法と思っておく。


【参考】

qiita.com

sshのAgent Forwarding

環境  CentOS7.0.1 

Agent Forwarding。
puttyだと、pargentで秘密鍵のpassfrazeを毎度入力しなくてよくするあれ。

今回localhostVirtualBoxから別のサーバーにssh
そこから更にsshしようとすると、passfrazeを聞かれる。
つまり

ローカル
  ↓
  ↓ Agent Forwardingしてsshログイン
  ↓
サーバーA
  ↓
  ↓ sshログイン
  ↓
サーバーB
  ↓
  ↓ sshログイン。passfraze聞かれる
  ↓
サーバーC

で、イロイロ調べたところ、sshでログイン後に別のサーバーに更にsshするときは、

$ ssh -A User@Server

と、-Aオプションをつけないと、Agent Forwardingされない。

そうするとサーバーAからBへもAgent Forwardingされ、BからCもpassfrazeなしで問題ないというわけ。

今までpargentとかに頼り切って、きちんと知らなかった。反省。


【参考】

qiita.com

【Vagrant】 複数台構成の調査

環境  Vagrant 1.8.1 VirtualBox 5.0.12

Vagrantによる複数VM環境の構築

Vagrantfileを以下のようにする。

Vagrant.configure(2) do |config|
  config.vm.provider "virtualbox" do |vb|
    vb.gui = true
  end

  config.vm.define "server1" do |server|
    config.vm.box = "bento/centos-7.1"

    server.vm.network "private_network", ip: "192.168.33.10"

    config.vm.provision "shell", path: "provision1.sh"
  end

  config.vm.define "server2" do |server|
    config.vm.box = "bento/centos-7.1"

    server.vm.network "private_network", ip: "192.168.33.11"

    config.vm.provision "shell", path: "provision2.sh"
  end

    # Plugin
    config.vbguest.auto_update = false
end

vagrant upすれば両方起動。

どちらかにしたいときは

PS> vagrant up server1
PS> vagrant up server2

とかでOK。

で、ちょっと気になった事を確認してみた。

  1. プロビジョニングは別のものを指定できる

当たり前だけど可能。
ただ、デフォルトのホストとのファイル共有はserver1もserver2も同じ。
なので同じファイルを使うようなときは注意が必要。

  1. それぞれのサーバーへの接続

ホスト -> server1 : ssh 127.0.0.1:2222
ホスト -> server2 : ssh 127.0.0.1:2200

server1 -> server2 : ssh 192.168.33.11
server2 -> server1 : ssh 192.168.33.10

となる。つまりprivate_networkを設定してないと、ゲスト間は接続できない。

yum localinstallでrpmをインストール

環境  CentOS 7.0 

最近知ったが、yum には直接rpmをインストールするyum localinstallというコマンドが存在する。

$ sudo yum localinstall jdk-8u40-linux-x64.rpm 
# or
$ sudo yum localinstall 'http://javadl.sun.com/webapps/download/AutoDL?BundleId=111740

のように、ローカルにDLしたrpmにも、web上のrpm urlにも使用可能。

知らなんだ。

Proxyを乗り越えろ!

環境  Vagrant 1.8.1 VirtualBox 5.0.12

という事で、プロキシのある環境でgitとか、Vagrant等、随分引っかかって苦労したので、メモっとく。

Linux全般 / wget / curl

基本的に環境変数が使われる。
以下を実行するか、.bash_profile等にセットすればよい。
大文字と小文字が、アプリケーションによって異なる場合がある。

$ export http_proxy=http://<ユーザー名>:<パスワード>@proxy.server:port
$ export https_proxy=https://<ユーザー名>:<パスワード>@proxy.server:port
$ export HTTP_PROXY=http://<ユーザー名>:<パスワード>@proxy.server:port
$ export HTTPS_PROXY=https://<ユーザー名>:<パスワード>@proxy.server:port

git

git configで設定。

$ git config --global http.proxy http://<ユーザー名>:<パスワード>@proxy.server:port
$ git config --global https.proxy http://<ユーザー名>:<パスワード>@proxy.server:port

yum

【追記】以下でもできますが、基本的に環境変数がセットされてればOKみたいです。

/etc/yum.confにproxyを設定する。
以下を追加

proxy=http://proxy.server:port
proxy_username=<ユーザー名>
proxy_password=<パスワード>

mercurial

~/.hgに設定を書いてもいいが、めったに使わないので、ワンライナーで。

$ hg --config http_proxy.host=http://<ユーザー名>:<パスワード>@proxy.server:port clone <リポジトリ> <ローカル名>

Vagrant

というか、vagrant upとかを使うコンソール。
Linux系なら、環境変数をセットすればよい。

$ export http_proxy=http://<ユーザー名>:<パスワード>@proxy.server:port
$ export https_proxy=https://<ユーザー名>:<パスワード>@proxy.server:port

VirtualBox

VirtualBoxの設定からプロキシをセット。
ただゲストOSがLinuxなら、.bash_profileに環境変数セットしても同じ

$ export http_proxy=http://<ユーザー名>:<パスワード>@proxy.server:port
$ export https_proxy=https://<ユーザー名>:<パスワード>@proxy.server:port

msysgit

gitが使えればいい気がするけど、wgetとかしたいとき。
基本的にはLinuxと同じく環境変数をセットすればいい。

export http_proxy=http://<ユーザー名>:<パスワード>@proxy.server:port
export https_proxy=https://<ユーザー名>:<パスワード>@proxy.server:port

これでOK。

【Play Framework】 PlayFramework最新版をインストール

環境   Play Framework 2.4.6 CentOS7.0

インストール

java,javacがなければ、インストールしておく。

$ # インストール
$ cd /usr/local/src
$ sudo wget https://downloads.typesafe.com/typesafe-activator/1.3.7/typesafe-activator-1.3.7-minimal.zip
$ sudo unzip typesafe-activator-1.3.7-minimal.zip
$ sudo chmod +x activator-1.3.7-minimal/activator

$ # コマンドをショートカットで作成
$ cd /usr/local/bin
$ sudo ln -s ../src/activator-1.3.7-minimal/activator .

$ # 確認
$ activator -h
Usage: activator <command> [options]
...<省略>


アプリケーションを作成

$ activator new myapp

Fetching the latest list of templates...

Browse the list of templates: http://typesafe.com/activator/templates
Choose from these featured templates or enter a template name:
  1) minimal-akka-java-seed
  2) minimal-akka-scala-seed
  3) minimal-java
  4) minimal-scala
  5) play-java
  6) play-scala
(hit tab to see a list of all templates)
> play-scala
OK, application "myapp" is being created using the "play-scala" template.

newすると、テンプレートを選択する。 activator new myapp play-scala のようにすれば、ワンライナーでテンプレートを選択できる。


アプリケーション実行

$ cd myapp
$ activator run

これでhttp://<ホスト名>:9000 にアクセスする事で、サンプルページにアクセスできる。 f:id:takafumi-s:20160111231303p:plain


おまけ:Vagrantで動かす

ポートをフォワードする必要がある。 Vagrantfileに以下を記述

Vagrant.configure(2) do |config|
  config.vm.network :forwarded_port, host: 9000, guest: 9000
end

これで`http://127.0.0.1:9000`にてアクセス可能。