php的preg_match 的問題
想要請問:如果使用preg_match,能不能抓到指定的字之後,再讀取前面的字串及字數
例如:
$string = 臺北市信義區市府路1號;
if (preg_match("/路/i", $string)) {
echo "有路";
} else {
echo "沒有路";
}
已抓到字串裡的路,但我想要再抓市府這兩個字,需要再怎麼寫?? 能否請幫我解答~~ 謝謝
preg_match 不是這麼用的
preg_match 是讓你用來「檢查資料是否符合自定格式」
例如:IP (nnn.nnn.nnn.nnn) 或 email address (xx.xx@xxx.xxx.xxx.xx)
preg_match 比較簡單的用法如下
1.PHP 的 preg_match 會回傳符合 Regular Expression「全部」的資料而非「部份」資料
2.拿到符合的資料後,再從裡面自己「切」出所要的資料
底下是 Step 1 的範例供參考
看看能不能用
<?php
echo isValid("高雄市三多路1號");
echo isValid("臺北市信義區市府路1號");
echo isValid("臺北市信義區忠孝東路1號");
function isValid($str) {
if (preg_match("/.{6}市.{6}區.{6}路.+號/m", $str, $arr)) {
echo $arr[0] . " is valid.\n";
} else {
echo $str . " is not valid.\n";
}
}
?>
還有
先到RegEx101去學習 Regular Expression
其實 preg_match 可以取得部分資料
不過要搭配正則中的集合 例如
$string = '臺北市信義區市府路1號';
if (preg_match('/(.*)市(.*)區(.*)路/i', $string, $matches)) {
print_r($matches[3]); // 市府
// echo "有路";
} else {
echo "沒有路";
}
其實 preg_match 可以取得部分資料
這是高手的進階用法
對初學者來說是兩面刄
的確是
所以我也認同要先學好正則再來使用這個函數XD
真的,我真的非常認同,因第一次用到這個函數,昨天有找詢了相關的資料,看到了很多的天書文字,例如
/^[\w-]+(.[\w-]+)*@[\w-]+(.[\w-]+)+$/
很佩服前輩們怎麼能用得如行雲流水一樣, 也很謝謝大家肯耐心的回答我! 海綿寶寶listennn08浩瀚星空淺水員japhenchen 非常的謝謝您們!
可以先了解正則表達式每個符號代表的意義
正則表達式線上產生器
也可以去海綿大提供的網站練習 這樣就會比較知道在寫什麼了
preg_match 這樣子用跟直接用 mb_strpos 有何差別??
這樣子用 preg_match 它可是會哭的。
你參考海綿寶寶給你的範例。
學習真正的正則方式。
了解一下各函數的實際用法。
不要惡搞用法啊。
最佳解就給海綿了。
最初的想法是,每個函數都去用看看,看哪個用起來最順就用那一個,我原本是先用了explode,但以 $string ='臺北市信義區市府路1號';
用了之後,想到它只能分析到市,
$string = "臺北市信義區市府路1號";
$arr = explode("市",$string);
foreach($arr as $v){
echo $v."";
}
echo "-------------";
我的想法是:如果又再用到區,它抓出來的會變成臺北市信義區,那是不是又要再用substr 再去尾~ 但會有人像我這樣子寫嗎? 我都有點懷疑我自己了,我不知道我這樣子的表達對不對,能明白我在講什麼嗎?!!!
其實,這些都是過程。
用explode來解也是一招。
不過認真來說,你還沒遇上真正的難判斷。
有那種沒路沒街的地址你知道嘛?還有那種沒xx號的。(真的有喔,映像好像是屏東那邊的地址,太久了我也忘了)
我也給你我的經驗好了。認真來說,海綿給的跟淺水員的用法我之前都用過。explode的跑法也跑過。
但就是沒辦法符合全部的地址。我後來的做法有兩種
1.郵政區號的資料庫:去中華郵政下載一個全台地址。看是要下載詳細版(包含區碼5碼的規則)還是簡易版。拿來做比對資料庫用。
優點準確度夠
其缺點是佔用空間。且開發也比較麻煩了點。
2.google的地理庫:
將地址喂給google的地理庫api。它會幫忙做區分跟解析。
優點簡單處理
缺點就是要錢,遇到不認識的地址還會亂跑很麻煩。
以上是我後來的經驗。給你參考。
<?php
$string ='臺北市信義區市府路1號';
if(preg_match("/([^市]+)市([^區]+)區([^路]+)路/u", $string, $mch)) {
echo "市:{$mch[1]} ";
echo "區:{$mch[2]} ";
echo "路:{$mch[3]} ";
} else {
echo "不符合";
}
preg_match不只可以檢查,也可以用()抓取資料分組
<?php
$addr = '高雄市鼓山區厚德一路1號';
preg_match('/.*區(?<road>[^路]+)路/u', $addr, $mat, PREG_OFFSET_CAPTURE);
echo "路名: {$mat["road"][0]}";
?>
輸出
路名: 厚德一
記得pattern 最後要加u不然中文檢查會出槌
改進一下,這樣可以避免沒寫區的毛病
$addr = '高雄市厚德一路1號';
preg_match('/.*[縣市鄉鎮區鄰里](?<road>[^路]+)路/u', $addr, $mat, PREG_OFFSET_CAPTURE);
echo "路名: {$mat["road"][0]}";
路名分析其實還滿難的,例如:大里路、市政路…
如果是給使用者輸入的,感覺用選單比較好
像上面有大大用{6}來抓固定中文字數的,遇到這種
台中市西屯區市政北七路168號
一定會只剩下"北七"路
還有台積電的網頁上的地址,也會切不好
https://www.tsmc.com/chinese/contact_us.htm#TSMC_fabs
新竹科學園區園區二路168號
我只是也想要寫看看郵遞區號,像這種的,http://zip5.5432.tw/