📄 cbregexp.cpp
字号:
// $Id: CBregexp.cpp,v 1.18 2005/04/17 10:01:02 genta Exp $
/*! @file
@brief BREGEXP Library Handler
Perl5互換正規表現を扱うDLLであるBREGEXP.DLLを利用するためのインターフェース
@author genta
@date Jun. 10, 2001
@date 2002/2/1 hor ReleaseCompileBufferを適宜追加
@date Jul. 25, 2002 genta 行頭条件を考慮した検索を行うように.(置換はまだ)
@date 2003.05.22 かろと 正規な正規表現に近づける
@date 2005.03.19 かろと リファクタリング。クラス内部を隠蔽。
*/
/*
Copyright (C) 2001-2002, genta
Copyright (C) 2002, novice, hor
Copyright (C) 2003, かろと
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented;
you must not claim that you wrote the original software.
If you use this software in a product, an acknowledgment
in the product documentation would be appreciated but is
not required.
2. Altered source versions must be plainly marked as such,
and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
*/
#include <stdio.h>
#include <string.h>
#include "CBregexp.h"
#include "etc_uty.h"
// Compile時、行頭置換(len=0)の時にダミー文字列(1つに統一) by かろと
const char CBregexp::m_tmpBuf[2] = "\0";
CBregexp::CBregexp() : m_pRegExp( NULL ),
m_ePatType( PAT_NORMAL ) // Jul, 25, 2002 genta
{
}
CBregexp::~CBregexp()
{
//<< 2002/03/27 Azumaiya
// 一応、クラスの終了時にコンパイルバッファを解放。
DeinitDll();
//>> 2002/03/27 Azumaiya
}
// Jul. 5, 2001 genta 引数追加。ただし、ここでは使わない。
char *
CBregexp::GetDllName( char* str )
{
return "BREGEXP.DLL";
}
/*!
DLLの初期化
関数のアドレスを取得してメンバに保管する.
@retval 0 成功
@retval 1 アドレス取得に失敗
*/
int CBregexp::InitDll(void)
{
// Apr. 15, 2002 genta
// CPPA.cpp を参考に設定を配列化した
const ImportTable table[] = {
{ &BMatch, "BMatch" },
{ &BSubst, "BSubst" },
{ &BTrans, "BTrans" },
{ &BSplit, "BSplit" },
{ &BRegfree, "BRegfree" },
{ &BRegexpVersion, "BRegexpVersion" },
{ NULL, 0 }
};
if( ! RegisterEntries( table )){
return 1;
}
// 2003.11.01 かろと 拡張した関数のアドレス取得
BMatchEx = (BREGEXP_BMatchEx)GetProcAddress( GetInstance(), "BMatchEx" );
BSubstEx = (BREGEXP_BSubstEx)GetProcAddress( GetInstance(), "BSubstEx" );
return 0;
}
/*!
BREGEXP構造体の解放
*/
int CBregexp::DeinitDll( void )
{
ReleaseCompileBuffer();
return 0;
}
/*! @brief 検索パターンが特定の検索パターンかチェックする
**
** @param[in] szPattern 検索パターン
**
** @retval 検索パターン文字列長
**
** @date 2005.03.20 かろと 関数に切り出し
*/
int CBregexp::CheckPattern(const char *szPattern)
{
static const char TOP_MATCH[] = "/^\\(*\\^/k"; //!< 行頭パターンのチェック用パターン
static const char DOL_MATCH[] = "/\\\\\\$$/k"; //!< \$(行末パターンでない)チェック用パターン
static const char BOT_MATCH[] = "/\\$\\)*$/k"; //!< 行末パターンのチェック用パターン
static const char TAB_MATCH[] = "/^\\(*\\^\\$\\)*$/k"; //!< "^$"パターンかをチェック用パターン
static const char LOOKAHEAD[] = "/\\(\\?[=]/k"; //!< "(?=" 先読み の存在チェックパターン
BREGEXP* sReg = NULL; //!< コンパイル構造体
char szMsg[80] = ""; //!< エラーメッセージ
int nLen; //!< 検索パターンの長さ
const char *szPatternEnd; //!< 検索パターンの終端
m_ePatType = PAT_NORMAL; //!< ノーマルは確定
nLen = strlen( szPattern );
szPatternEnd = szPattern + nLen;
// パターン種別の設定
if( BMatch( TOP_MATCH, szPattern, szPatternEnd, &sReg, szMsg ) > 0 ) {
// 行頭パターンにマッチした
m_ePatType |= PAT_TOP;
}
BRegfree(sReg);
sReg = NULL;
if( BMatch( TAB_MATCH, szPattern, szPatternEnd, &sReg, szMsg ) > 0 ) {
// 行頭行末パターンにマッチした
m_ePatType |= PAT_TAB;
}
BRegfree(sReg);
sReg = NULL;
if( BMatch( DOL_MATCH, szPattern, szPatternEnd, &sReg, szMsg ) > 0 ) {
// 行末の\$ にマッチした
// PAT_NORMAL
} else {
BRegfree(sReg);
sReg = NULL;
if( BMatch( BOT_MATCH, szPattern, szPatternEnd, &sReg, szMsg ) > 0 ) {
// 行末パターンにマッチした
m_ePatType |= PAT_BOTTOM;
} else {
// その他
// PAT_NORMAL
}
}
BRegfree(sReg);
sReg = NULL;
if( BMatch( LOOKAHEAD, szPattern, szPattern + nLen, &sReg, szMsg ) > 0 ) {
// 先読みパターンにマッチした
m_ePatType |= PAT_LOOKAHEAD;
}
BRegfree(sReg);
sReg = NULL;
return (nLen);
}
/*! @brief ライブラリに渡すための検索?置換パターンを作成する
**
** @note szPattern2: == NULL:検索 != NULL:置換
**
** @param[in] szPattern 検索パターン
** @param[in] szPattern2 置換パターン(NULLなら検索)
** @param[in] szAdd2 置換パターンの後ろに付け加えるパターン($1など)
** @param[in] bOption 検索オプション
**
** @retval ライブラリに渡す検索パターンへのポインタを返す
** @note 返すポインタは、呼び出し側で delete すること
**
** @date 2003.05.03 かろと 関数に切り出し
*/
char* CBregexp::MakePatternSub( const char* szPattern, const char* szPattern2, const char* szAdd2, int bOption )
{
static const char DELIMITER = '\xFF'; //<! デリミタ
int nLen; //!< szPatternの長さ
int nLen2; //!< szPattern2 + szAdd2 の長さ
// 検索パターン作成
char *szNPattern; //!< ライブラリ渡し用の検索パターン文字列
char *pPat; //!< パターン文字列操作用のポインタ
nLen = strlen(szPattern);
if (szPattern2 == NULL) {
// 検索(BMatch)時
szNPattern = new char[ nLen + 15 ]; // 15:「s///option」が余裕ではいるように。
pPat = szNPattern;
*pPat++ = 'm';
} else {
// 置換(BSubst)時
nLen2 = strlen(szPattern2) + strlen(szAdd2);
szNPattern = new char[ nLen + nLen2 + 15 ];
pPat = szNPattern;
*pPat++ = 's';
}
*pPat++ = DELIMITER;
while (*szPattern != '\0') { *pPat++ = *szPattern++; }
*pPat++ = DELIMITER;
if (szPattern2 != NULL) {
while (*szPattern2 != '\0') { *pPat++ = *szPattern2++; }
while (*szAdd2 != '\0') { *pPat++ = *szAdd2++; }
*pPat++ = DELIMITER;
}
*pPat++ = 'k'; // 漢字対応
*pPat++ = 'm'; // 複数行対応(但し、呼び出し側が複数行対応でない)
if( !(bOption & bIgnoreCase) ) { // 2002/2/1 hor IgnoreCase オプション追加 マージ:aroka
*pPat++ = 'i'; // 同上
}
*pPat = '\0';
return szNPattern;
}
/*!
** 行末文字の意味がライブラリでは \n固定なので、
** これをごまかすために、ライブラリに渡すための検索?置換パターンを工夫する
**
** 行末文字($)が検索パターンの最後にあり、その直前が [\r\n] でない場合に、
** 行末文字($)の手前に ([\r\n]+)を補って、置換パターンに $(nParen+1)を補う
** というアルゴリズムを用いて、ごまかす。
**
** @note szPattern2: == NULL:検索 != NULL:置換
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -