2018年10月24日 星期三

找回 Nodepad++ 當掉崩潰不見的檔案內容

Nodepad++ 版本:7.5.7 (32bit)

情況:使用 Nodepad++ 編輯文字檔儲存時,突然當掉崩潰,重開 Nodepad++ 後,原來編輯的檔案內容全被清空不見。

解決方式:
查看「設定」->「使用者自訂」裡的「備份」,查看「檔案群組快照和定期備份」中的「備份路徑」位置。
到「備份路徑」位置,幸運的話,可找到「檔案名稱@時間」的備份檔案。
將檔名後面的「@時間」去掉,就是一般的文字檔。這可以找回之前某一時間點的備份內容,雖然還是會遺失後來編輯的內容,但至少可救回之前的內容。



另外自訂備份:
如果對上面的自動備份設定不放心,該設定下面還有一個「備份」的設定。
我測試的效果是,

「簡易備份」:每次儲存時將未編輯前的檔案,複製一份「原檔名」的檔案到「自訂備份資料夾」,該資料夾只會有一份該檔名的備份檔。

「詳細備份」:每次儲存時將未編輯前的檔案,複製一份「原檔名@時間」到「自訂備份資料夾」,該資料夾會有多份該檔名的不同時間點的備份檔。

最後我選用「詳細備份」,因為可避免檔案路徑不同,但檔名相同的檔案,備份檔案一定會互相覆蓋的情況。




參考:
Notepad ++ Crashed? Lost Notepad ++ Files? Restore Right Now! – EaseUS
file - Lost code lines when Notepad++ crashed - Stack Overflow


2018年9月6日 星期四

PHP strtotime 月份加減

PHP 的 strtotime 可以進行月份的加減。
但 PHP 進行時,會保留原來的「日」,再判斷是否需進行時間的偏移,所以可能導致最終的日期跟預想的不一樣。
例如:
$cur_date = "2016-03-31";
var_dump(date("Y-m-d", strtotime("-1 month", strtotime($cur_date))));//2016-03-02
var_dump(date("Y-m-d", strtotime("+1 month", strtotime($cur_date))));//2016-05-01
2016-03-31 減一個月變成 2016-02-31,但2016年2月只到29號,所以 2016-02-31 => 2016-03-02
2016-03-31 加一個月變成 2016-04-31,但4月只到30號,所以 2016-04-31 => 2016-05-01

這結果,可能跟預想的不太一樣。
但如果只是要取月份加減後的月初、月底,或只著重在結果的月分準確即可,
那可使用「first day of」(取月初)、「last day of」(取月底)來處理。
加減過程中,沒了原本的「日」,也就沒最後因為「日」而導致月份的偏移了。
$cur_date = "2016-03-31";
var_dump(date("Y-m-d", strtotime("first day of -1 month", strtotime($cur_date))));//2016-02-01
var_dump(date("Y-m-d", strtotime("last day of -1 month", strtotime($cur_date))));//2016-02-29
var_dump(date("Y-m-d", strtotime("first day of +1 month", strtotime($cur_date))));//2016-04-01
var_dump(date("Y-m-d", strtotime("last day of +1 month", strtotime($cur_date))));//2016-04-30


最後測試一下跨年是否有影響。
結果:跨年度的話,似乎「年」能先準確的計算出來。至於最後會不會自動偏移,一樣是看該「年-月」是否有該日期決定。
$cur_date = "2017-03-29";
var_dump(date("Y-m-d", strtotime("-13 month", strtotime($cur_date))));//2017-02-29

$cur_date = "2017-03-30";
var_dump(date("Y-m-d", strtotime("-13 month", strtotime($cur_date))));//2016-03-01
var_dump(date("Y-m-d", strtotime("first day of -13 month", strtotime($cur_date))));//2016-02-01
var_dump(date("Y-m-d", strtotime("last day of -13 month", strtotime($cur_date))));//2016-02-29


參考:
令人困惑的strtotime | 风雪之隅


2018年8月19日 星期日

JavaScript RegExp 的 lastIndex 屬性

JavaScript 正規表示式 RegExp 物件,當有使用「g」global match 參數時,
會有一個 lastIndex  屬性,記錄上一次批配到的字串,後面的位置(預設值為0)。

RegExp.lastIndex  屬性:
  1. RegExp.exec()、RegExp.test(),都是以 lastIndex 當作匹配比對起點
  2. 當匹配比對失敗,lastIndex 會重設為 0
  3. RegExp.lastIndex 值可手動設定

範例:
var str = 'abcde';
var RegExpObj = new RegExp('b', 'g');
RegExpObj.lastIndex; //0  預設值為 0

//第一次比對,比對成功,lastIndex 變為 2
RegExpObj.test(str); // true
RegExpObj.lastIndex; //2

//第二次比對,從字串位置 2 開始比對,比對失敗,lastIndex 自動重置為 0
RegExpObj.test(str); // false
RegExpObj.lastIndex; //0

//第三次比對,又從字串位置 0 開始比對,比對成功,lastIndex 變為 2
RegExpObj.test(str); // true
RegExpObj.lastIndex; //2

//手動將 lastIndex 設為 1,再次比對,可成功比對到字串位置 1 的 「b」
RegExpObj.lastIndex=1; 
RegExpObj.lastIndex; //1
RegExpObj.test(str); // true


參考:
JavaScript lastIndex 属性
regexp.lastIndex - JavaScript | MDN
regex - Bug with RegExp in JavaScript when do global search - Stack Overflow

PHP 判斷是否為搜尋引擎爬蟲訪問網頁

要判斷是否為搜尋引擎爬蟲訪問網頁,可以從 $_SERVER["HTTP_USER_AGENT"] 字串判斷。
一般有以下兩種判斷方法。
方法1:找出「搜尋引擎爬蟲」可能的 User-Agent,符合的即為「搜尋引擎爬蟲」。
方法2:找出「瀏覽器」可能的 User-Agent,不符合的即是「網路爬蟲」,這邊當做都是「搜尋引擎爬蟲」。當然,如果是要較精準的分辨出「搜尋引擎爬蟲」和其他網路爬蟲,還是要使用方法1。

一般情況,大都只是要分辨出所有網路爬蟲(搜尋引擎、其他爬蟲),所以這邊選用方法2,因為常用的瀏覽器 User-Agent,比較容易知道、也可自己測試取得,
而且一般使用者使用瀏覽器時,應該都會傳送正常的 User-Agent。
所以應該可以放心將不符合的當作是網路爬蟲(搜尋引擎爬蟲)。
檢查方法:
/**
 * 判斷是否為網路爬蟲
 * @return boolean
 */
function webCrawlerDetect() {
    $pattern = '/firefox|chrome|msie|opera|safari|edge|yabrowser|maxthon|konqueror|netscape|lynx|links/i';//瀏覽器
    return !(isset($_SERVER['HTTP_USER_AGENT']) && preg_match($pattern, $_SERVER['HTTP_USER_AGENT']));
}
其他:
可能會在瀏覽器的 User-Agent 發現其他瀏覽器的關鍵字,
例如 Chrome、Edge 的 User-Agent 可能發現 Mozilla、Safari。
這是因為有的網站會針對不同瀏覽器特有功能,做適當的回應。
所以當新的瀏覽器,也相容其他瀏覽器特有功能時,瀏覽器便用此方式,讓網站也能如期顯示。
參考 WebAIM: History of the browser user-agent string

2018年7月28日 星期六

Netbeans 設定預設使用 UTF8 編碼開啟檔案

Netbeans 專案可以設定使用的文字編碼,例如設定為 UTF8,
但即使在 UTF8 編碼的專案中,嘗試「開啟」或「Diff to...」非專案資料夾內的檔案,
能會使用原本預設的編碼開啟,而不是專案設定的編碼。
所以可能出現「cannot be safely opened with encoding x-windows-950」之類的錯誤訊息。
(嘗試使用預設的 BIG5 編碼開啟不是 BIG5 編碼的檔案,強制打開後會顯示亂碼)

若預開啟的檔案維 UTF8,可以將 Netbeans 預設開啟檔案的編碼改為 UTF-8
  1. 找到 netbeans.conf 設定檔
    一般在「C:\Program Files\NetBeans 8.2\etc\netbeans.conf」
  2. 將設定檔中的 netbeans_default_options 選項,加上(或修改為)「-J-Dfile.encoding=UTF-8」。
    例如:
    netbeans_default_options="-J-client -J-Xss2m -J-Xms32m -J-Dapple.laf.useScreenMenuBar=true -J-Dapple.awt.graphics.UseQuartz=true -J-Dsun.java2d.noddraw=true -J-Dsun.java2d.dpiaware=true -J-Dsun.zip.disableMemoryMapping=true"
    
    在最後加上「-J-Dfile.encoding=UTF-8」,再重開 Netbeans 即可。
    netbeans_default_options="-J-client -J-Xss2m -J-Xms32m -J-Dapple.laf.useScreenMenuBar=true -J-Dapple.awt.graphics.UseQuartz=true -J-Dsun.java2d.noddraw=true -J-Dsun.java2d.dpiaware=true -J-Dsun.zip.disableMemoryMapping=true -J-Dfile.encoding=UTF-8"
    


參考:
How to change default encoding in NetBeans 8.1