當前位置:首頁 » 編程語言 » 正則sqlphp

正則sqlphp

發布時間: 2023-07-17 09:06:57

A. php中正則問題

首先贊揚一下樓主的提問方式:
1. 對問題描述得很清晰;
2. 給出了匹配的範例文本;
3. 指定了正則式所在的語言。
這才應該是規范合理的提問。

言歸正傳,先根據問題,寫出正則,然後落實到PHP語言。如果對分析過程不感興趣,請直接pagedown看答案。

1. 基礎
需要匹配的關鍵詞為:test,你好,程序,分類。
正則表達式:/test|你好|程序|分類/i
(i是表示大小寫不敏感模式。如果指定匹配小寫的test,則可以去掉i)

2. 限制條件
a. 不在標簽內部,例如<img src=asdasda.jpg alt="test" title="你好">,裡面雖然有test和你好,但這不滿足要求;
b. 本身無鏈接。例如,<a href="link1" alt="程序設計">程序設計</a>中,>程序設計<中的程序由於處於<a..>程序設計</a>之間,同樣不滿足要求。

根據以上限制,寫出純粹的正則式(並不能直接用在php中):
(?<!<(?:a|img)[^<>]*)(test|你好|程序|分類)(?![^<>]*</a>)
它表示,(test|你好|程序|分類)的緊臨左側不能出現<a..標簽,或者<img標簽;緊臨右側不能出現</a>標簽。

「緊臨」二字至關重要,它將無直接關系的<>都忽略掉,才確保條件的正確執行。怎樣實現這一點呢?我使用的是[^<>]*。

正則式的部分這里就交待清楚了。下面將正則式應用到PHP中。

3. php正則式
php使用的正則表達式是PCRE的,它不支持在lookbehind里使用無限量詞,即(?<!<(?:a|img)[^<>]*)部分不被PCRE支持。沒關系,可以修改之。
(?<!(?:<a|<img))([^<>]*)(test|你好|程序|分類)(?![^<>]*(?:>|</a>))

與2中的正則式相比,前者$1即為所求,其餘部分只匹配,不消耗字元;而後者$2為所求,還需要對$1進行處理。

4. php細節
我使用preg_replace_callback函數,以便自定義替換過程。代碼如下,隨手注釋:

<?php

//此處使用heredoc語法,以便支持復雜的長文本。
$x=<<<EOT
請從以下推薦分類中選擇合適的分類:<br>電腦/網路 -> <a href="link1" alt="程序設計">程序設計</a><br>
電腦/網路 -> 操作系統/系統故障<br>
<br>
如果沒有合適的推薦分類,建議您更改分類,有助於獲得准確解答 <br>
<img src=asdasda.jpg alt="test" title="你好"><br>
您還可以輸入1381字<br>
test<br>
輸入內容已經達到長度限制<br>
EOT;

//關鍵詞數組
$a=array(
1 => "test",
2 => "你好",
3 => "程序" ,
4 => "分類"
);

//記號數組,用於記錄哪些匹配是已經替換了的。因為樓主指定「每個詞只匹配一次」。
$index=array();

function compute_replacement($groups) {

global $a;
global $index;

if ($index[$groups[2]])
{
//如果該關鍵詞已經被處理過,那麼直接返回整個字串($groups[0]),不作處理。
return $groups[0];
}

//查詢該關鍵詞在數組中的位置,確定序號,以便生成href="1.html"之類鏈接地址。
$in=array_search($groups[2],$a);

//將處理過的關鍵詞標記為已處理,避免重復。
$index[$groups[2]]=1;

//返回處理好的文本。
return "$groups[1]<a href=\"$in.html\" title=\"$groups[2]\">$groups[2]</a>";
}

$r= preg_replace_callback('%(?<!<)([^<>]*)(test|你好|程序|分類)(?![^<>]*(?:>|</a>))%s', compute_replacement, $x);

echo $r;
?>

輸出的結果為:

請從以下推薦分類中選擇合適的<a href="4.html" title="分類">分類</a>:<br>電腦/網路 -> <a href="link1" alt="程序設計">程序設計</a><br>
電腦/網路 -> 操作系統/系統故障<br>
<br>
如果沒有合適的推薦分類,建議您更改分類,有助於獲得准確解答 <br>

<img src="asdasda.jpg" alt="test" title="你好"><br>
您還可以輸入1381字<br>
<a href="1.html" title="test">test</a><br>
輸入內容已經達到長度限制<br></body>

註:這里的格式不好,建議去「參考資料」所指向的地址察看更易讀版本的解答。

正則表達式論壇:
正則表達式博客:

附:匹配圖。高亮部分為匹配結果。

B. 這一段php中正則表達式的詳細含義……

拆分這段正則:

  1. '

  2. (and|or)\b.+?(>|<|=|in|like)

  3. \/\*.+?\*\/

  4. <\s*script\b

  5. \bEXEC\b

  6. UNION.+?SELECT

  7. UPDATE.+?SET

  8. INSERT\s+INTO.+?VALUES

  9. (SELECT|DELETE).+?FROM

  10. (CREATE|ALTER|DROP|TRUNCATE)\s+(TABLE|DATABASE)


你仔細看看,每一條都是對應一種資料庫語句可能會出現的情況(除了第3條):


第一條是 單引號,單引號在資料庫語句中的作用不用我多說了

第二條是 模糊孫查詢

第三條是「*.*」這種資料庫萬能語句

第四條我覺得可能是<script>的html標簽

第五條是 exec資料庫動態查詢語句

第六條是 UNION聯合查詢

第七條是 資料庫更新語句

第八條是 數據表插入

第九條是 查詢或刪除數據

第十條是 創建、修改、刪除等資料庫操作


而這條語句的作用就是使用正則從字元串中查找是否存在資料庫操作相關的敏感字元串,從而對該字元串進行一定的處理,保障伺服器安全。


(以上)

C. 如何在sql語句中使用正則表達式

sqlserver中,主要有regexp_like,regexp_replace,regexp_substr,regexp_instr四個正則表達式函數。

1、regexp_like:

regexp_like(x,pattern[,match_option]),查看x是否與pattern相匹配,該函數還可以提供一個可選的參數match_option字元串說明默認的匹配選項。match_option的取值如下:

'c' 說明在進行匹配時區分大小寫(預設值);

'i' 說明在進行匹配時不區分大小寫;

'n' (.)點號能表示所有單個字元,包括換行(俺還不知道什麼地方有用到換行.只知道sql裡面可以用chr(10)表示換行、

'm' 字元串存在換行的時候當作多行處理.這樣$就可匹配每行的結尾.不然的話$只匹配字元串最後的位置、

示例:

select * from emp where regexp_like(ename,'^a[a-z]*n$');

可以查找ename中以a開頭以n結尾的行.例如ename為arwen或arwin或anden.但Arwen不能被匹配.因為默認是區分大小寫.如果是

select * from emp where regexp_like(ename,'^a[a-z]*n$','i')

則可以查找ename為Arwen的行記錄。

2、regexp_instr:

REGEXP_INSTR(x,pattern[,start[,occurrence[,return_option[, match_option]]]])用於在x中查找pattern。返回pattern在x中出現的位置。匹配位置從1開始。可以參考字元串函數 INSTR(),參數相關:

'start' 開始查找的位置;

'occurrence' 說明應該返回第幾次出現pattern的位置;

'return_option' 說明應該返回什麼整數。若該參數為0,則說明要返回的整數是x中的一個字元的位置;若該參數為非0的整數,則說明要返回的整數為x中出現在pattern之後 的字元的位置;

'match_option' 修改默認的匹配設置.與regexp_like裡面的相同.

示例:

DECLARE

V_RESULT INTEGER ;

BEGIN

SELECT REGEXP_INSTR('hello world','o',1,1,0) INTO V_RESULT

FROM DUAL;

DBMS_OUTPUT.PUT_LINE(V_RESULT);

END;

結果為5,即字母o第一個次出現的位置。

如果regexp_instr('hello world','o',1,1,n)其中n為除0之外的整數。比如1,3。則結果為6.表示第一次出現字母o的後面一個字元的位置。

如果regexp_instr('hello world','o',1,2,0)則結果為9.表示第二次出現字母o的位置.

3、regexp_replace:

REGEXP_REPLACE(x,pattern[,replace_string[,start[,occurrence[, match_option]]]])用於在x中查找pattern,並將其替換為replae_string。可以參考字元串函數 REPLACE(),參數同REGEXP_INSTR函數

示例:

DECLARE

V_RESULT varchar2(90);

BEGIN

SELECT REGEXP_REPLACE('hello world','o','x',1,1) INTO V_RESULT

FROM DUAL;

DBMS_OUTPUT.PUT_LINE(V_RESULT);

END;

結果為hellx world.

如果REGEXP_REPLACE('hello world','o','x'),則結果為hellx wxrld.

如果 REGEXP_REPLACE('hello world','o','x',1,2)則結果為hello wxrld.

4、regexp_substr:

REGEXP_SUBSTR(x,pattern[,start[,occurrence[, match_option]]])用於在x中查找pattern並返回。可以參考字元串函數 SUBSTR(),參數同REGEXP_INSTR函數.

例如:

DECLARE

V_RESULT VARCHAR2(255);

BEGIN

SELECT REGEXP_SUBSTR('hello world','l{2}') INTO V_RESULT

FROM DUAL;

DBMS_OUTPUT.PUT_LINE(V_RESULT);

END ;

結果為ll

查詢到匹配的字元串才返回匹配的字元.沒查到就返回空。

D. php防止sql注入示例分析和幾種常見攻擊正則

functioncustomError($errno,$errstr,$errfile,$errline)
{
echo"Errornumber:[$errno],erroronline$errlinein$errfile
";
die();
}
set_error_handler("customError",E_ERROR);
$getfilter="'|(and|or)\b.+?(>|<|=|in|like)|\/\*.+?\*\/|<\s*script\b|\bEXEC\b|UNION.+?SELECT|UPDATE.+?SET|INSERT\s+INTO.+?VALUES|(SELECT|DELETE).+?FROM|(CREATE|ALTER|DROP|TRUNCATE)\s+(TABLE|DATABASE)";
$postfilter="\b(and|or)\b.{1,6}?(=|>|<|\bin\b|\blike\b)|\/\*.+?\*\/|<\s*script\b|\bEXEC\b|UNION.+?SELECT|UPDATE.+?SET|INSERT\s+INTO.+?VALUES|(SELECT|DELETE).+?FROM|(CREATE|ALTER|DROP|TRUNCATE)\s+(TABLE|DATABASE)";
$cookiefilter="\b(and|or)\b.{1,6}?(=|>|<|\bin\b|\blike\b)|\/\*.+?\*\/|<\s*script\b|\bEXEC\b|UNION.+?SELECT|UPDATE.+?SET|INSERT\s+INTO.+?VALUES|(SELECT|DELETE).+?FROM|(CREATE|ALTER|DROP|TRUNCATE)\s+(TABLE|DATABASE)";
functionStopAttack($StrFiltKey,$StrFiltValue,$ArrFiltReq)
{
if(is_array($StrFiltValue))
{
$StrFiltValue=implode($StrFiltValue);
}
if(preg_match("/".$ArrFiltReq."/is",$StrFiltValue)==1&&!isset($_REQUEST['securityToken']))
{
slog("

操作IP:".$_SERVER["REMOTE_ADDR"]."
操作時間:".strftime("%Y-%m-%d%H:%M:%S")."
操作頁面:".$_SERVER["PHP_SELF"]."
提交方式:".$_SERVER["REQUEST_METHOD"]."
提交參數:".$StrFiltKey."
提交數據:".$StrFiltValue);
print"resultnotice:Illegaloperation!";
exit();
}
}
foreach($_GETas$key=>$value)
{
StopAttack($key,$value,$getfilter);
}
foreach($_POSTas$key=>$value)
{
StopAttack($key,$value,$postfilter);
}
foreach($_COOKIEas$key=>$value)
{
StopAttack($key,$value,$cookiefilter);
}

functionslog($logs)
{
$toppath="log.htm";
$Ts=fopen($toppath,"a+");
fputs($Ts,$logs." ");
fclose($Ts);
}
?>

E. sql正則表達式常用符號

SQL的查詢語句中,有時會需要引進正則表達式為其復雜搜索指定模式。下面給出一些Regexp在
MYSQL語句中應用(非全部):
1) ^
匹配字元串的開始部分。
mysql> SELECT 'fo\nfo' REGEXP '^fo$'; -> 0mysql> SELECT 'fofo' REGEXP '^fo'; -> 12) $
匹配字元串的結束部分。
mysql> SELECT 'fo\no' REGEXP '^fo\no$'; -> 1mysql> SELECT 'fo\no' REGEXP '^fo$'; -> 03) .
匹配任何字元(包括回車和新行)。
mysql> SELECT 'fofo' REGEXP '^f.*$'; -> 1mysql> SELECT 'fo\r\nfo' REGEXP '^f.*$'; -> 14)
[:character_class:]
在括弧表達式中(使用[和]),[:character_class:]表示與術語類的所有字元匹配的字元類。標準的類名稱是:
alnum
文字數字字元
alpha
文字字元
blank
空白字元
cntrl
控制字元
digit
數字字元
graph
圖形字元
lower
小寫文字字元
print
圖形或空格字元
punct
標點字元
space
空格、製表符、新行、和回車
upper
大寫文字字元
xdigit
十六進制數字字元
它們代表在ctype(3)手冊頁面中定義的字元類。特定地區可能會提供其他類名。字元類不得用作范圍的端點。
mysql> SELECT 'justalnums' REGEXP '[[:alnum:]]+'; -> 1
mysql> SELECT '!!' REGEXP '[[:alnum:]]+'; -> 0
5) [[:<:]], [[:>:]]
這些標記表示word邊界。它們分別與word的開始和結束匹配。word是一系列字字元,其前面和後面均沒有字
字元。字字元是alnum類中的字母數字字元或下劃線(_)。
mysql> SELECT 'a word a' REGEXP '[[:<:]]word[[:>:]]'; -> 1mysql> SELECT 'a xword a' REGEXP
'[[:<:]]word[[:>:]]'; -> 0要想在正則表達式中使用特殊字元的文字實例,應在其前面加上2個反斜杠「\」字元。
MySQL解析程序負責解釋其中一個,正則表達式庫負責解釋另一個。例如,要想與包含特殊字元「+」的字元
串「1+2」匹配,在下面的正則表達式中,只有最後一個是正確的:
mysql> SELECT '1+2' REGEXP '1+2'; -> 0mysql> SELECT '1+2' REGEXP '1\+2'; -> 0mysql> SELECT
'1+2' REGEXP '1\\+2'; -> 1 其他的有關Regexp的語法,可直接參考下表:字元 含意
\ 做為轉意,即通常在"\"後面的字元不按原來意義解釋,如/b/匹配字元"b",當b前面加了反斜桿後/\b/,轉意
為匹配一個單詞的邊界。
-或-
對正則表達式功能字元的還原,如"*"匹配它前面元字元0次或多次,/a*/將匹配a,aa,aaa,加了"\"後,/a\*/將
只匹配"a*"。
^ 匹配一個輸入或一行的開頭,/^a/匹配"an A",而不匹配"An a"
$ 匹配一個輸入或一行的結尾,/a$/匹配"An a",而不匹配"an A"
* 匹配前面元字元0次或多次,/ba*/將匹配b,ba,baa,baaa
+ 匹配前面元字元1次或多次,/ba*/將匹配ba,baa,baaa
? 匹配前面元字元0次或1次,/ba*/將匹配b,ba
(x) 匹配x保存x在名為$1...$9的變數中
x|y 匹配x或y
{n} 精確匹配n次
{n,} 匹配n次以上
{n,m} 匹配n-m次
[xyz] 字元集(character set),匹配這個集合中的任一一個字元(或元字元)
[^xyz] 不匹配這個集合中的任何一個字元
[\b] 匹配一個退格符
\b 匹配一個單詞的邊界
\B 匹配一個單詞的非邊界
\cX 這兒,X是一個控制符,/\cM/匹配Ctrl-M
\d 匹配一個字數字元,/\d/ = /[0-9]/
\D 匹配一個非字數字元,/\D/ = /[^0-9]/
\n 匹配一個換行符
\r 匹配一個回車符
\s 匹配一個空白字元,包括\n,\r,\f,\t,\v等
\S 匹配一個非空白字元,等於/[^\n\f\r\t\v]/
\t 匹配一個製表符
\v 匹配一個重直製表符
\w 匹配一個可以組成單詞的字元(alphanumeric,這是我的意譯,含數字),包括下劃線,如[\w]匹配
"$5.98"中的5,等於[a-zA-Z0-9]
\W 匹配一個不可以組成單詞的字元,如[\W]匹配"$5.98"中的$,等於[^a-zA-Z0-9]。

熱點內容
cryengine源碼 發布:2025-02-08 09:50:58 瀏覽:389
aardio可以反編譯嗎 發布:2025-02-08 09:50:53 瀏覽:480
公司營業執照密碼是什麼 發布:2025-02-08 09:47:56 瀏覽:852
體驗腳本 發布:2025-02-08 09:46:15 瀏覽:688
醫學生需要什麼配置的筆記本 發布:2025-02-08 09:45:34 瀏覽:770
騷擾電話資料庫 發布:2025-02-08 09:45:34 瀏覽:177
u盤文件加密器 發布:2025-02-08 09:40:35 瀏覽:769
plc數據存儲app 發布:2025-02-08 09:37:17 瀏覽:708
伺服器的峰值高低有什麼區別 發布:2025-02-08 09:35:46 瀏覽:689
maven預編譯 發布:2025-02-08 09:20:34 瀏覽:755