조건에 맞는 모든 문자열을 정기적으로 교체하는 PHP의 preg_replace() 메서드에 대해

不言
풀어 주다: 2023-04-01 16:36:01
원래의
2577명이 탐색했습니다.

이 글에서는 주로 PHP의 모든 정규 문자열을 preg_replace()로 정기적으로 교체하는 방법을 소개합니다. 이제는 특정 참조 값이 있으므로 이를 참조할 수 있습니다.

PHP preg_replace() 정규 교체 , Javascript의 일반적인 교체와 달리 PHP preg_replace()는 기본적으로 조건과 일치하는 기호가 있는 모든 요소를 ​​교체합니다

프로그램으로 처리해야 하는 데이터는 항상 데이터베이스 사고로 미리 설계되거나 데이터베이스 구조를 사용하여 저장할 수 없습니다.
예를 들어 템플릿 엔진 구문 분석 템플릿, 스팸에 민감한 정보 필터링 등
일반적으로 이 경우 정규 표현식을 사용하여 preg_match를 일치시키고 규칙에 따라 preg_replace를 바꿉니다.
그러나 일반 애플리케이션에서는 데이터베이스 CRUD에 지나지 않으며 정규식을 조작할 기회가 거의 없습니다.
앞서 말한 대로 두 가지 시나리오가 있습니다. 즉, 대체를 사용한 매칭 처리를 사용한 통계 분석입니다.

PHP preg_replace() 일반 교체, Javascript 일반 교체와 달리 PHP preg_replace()는 기본적으로 기호가 조건과 일치하는 모든 요소를 ​​교체합니다.

preg_replace (正则表达式, 替换成, 字符串, 最大替换次数【默认-1,无数次】, 替换次数)
로그인 후 복사

대부분의 언어에서 정규 표현식은 유사하지만 미묘한 차이점도 있습니다.

PHP 정규 표현식

+은 이전 하위 표현식과 여러 번 일치합니다. 예를 들어, "zo+"는 "zo" 및 "zoo"와 일치할 수 있지만 "z"는 일치하지 않습니다. +는 이전 하위 표현식과 0회 일치하거나 일치합니다. 예: "do(es. )?"는 "does"에서 "does" 또는 "do"와 일치할 수 있습니다. ?는 {0,1}n과 동일합니다. n은 음수가 아닙니다. 정수입니다. 특정 횟수와 일치합니다. 예: "o{ 2}"는 "Bob"의 "o"와 일치할 수 없지만 "food"의 2개의 o와 일치할 수 있습니다. {n,}n. 음수가 아닌 정수입니다. 최소 n번 일치합니다. 예를 들어, "o{2,}"는 "Bob"의 "o"와 일치할 수 없지만 "foooood"의 모든 "o{1,}"와 일치할 수 있습니다. "o+"는 다음과 같습니다. {n,m}M과 n은 모두 음수가 아닌 정수입니다. 여기서 n<=m은 최대 m번입니다. 3}"는 "fooooood"의 처음 3개의 o와 일치합니다. "o?"에 주의하세요. 두 숫자 사이에 공백이 있어서는 안 됩니다. ?이 문자 뒤에 다른 제한 기호(*,+ ,?,{n},{n,},{n,m}) 나중에 일치 모드는 non-greedy 모드이며, 기본 Greedy 모드는 검색된 문자열과 최대한 일치하지 않습니다. 예를 들어, "oooo" 문자열의 경우 "o?"는 단일 "o"와 일치하고 "o+"는 모든 "o"와 일치합니다. "n"을 제외한 모든 단일 문자와 일치합니다. "n"을 포함하여 일치하려면 "[sS]"와 같은 패턴을 사용하고 이 일치 항목을 얻을 수 있습니다. VBScript의 SubMatches 컬렉션을 사용하여 생성된 Matches 컬렉션에서 가져옵니다. JScript에서는 $0...$9 속성을 사용하여 괄호를 일치시키려면 (?:pattern) 패턴과 일치하지만 일치하는 결과를 얻지 못합니다. 즉, 가져오지 않는 일치는 나중에 사용하기 위해 저장되지 않습니다. 이는 또는 문자 "(|)"를 사용하여 패턴의 일부를 결합할 때 유용합니다. 예를 들어, "industr(?:y|ies)"는 "industry|industries"보다 간단한 표현입니다. (?=pattern)정방향 긍정 조회는 패턴과 일치하는 문자열의 시작 부분에서 검색 문자열을 일치시킵니다. 이는 가져오지 않는 일치입니다. 즉, 나중에 사용하기 위해 일치 항목을 가져올 필요가 없습니다. 예를 들어, "Windows(?=95|98|NT|2000)"는 "Windows2000"의 "Windows"와 일치할 수 있지만 "Windows3.1"의 "Windows"와 일치할 수는 없습니다. 프리페치는 문자를 소비하지 않습니다. 즉, 일치가 발생한 후 다음 일치 항목에 대한 검색은 프리페치를 포함하는 문자 뒤에서 시작하는 것이 아니라 마지막 일치 직후에 시작됩니다. (?!pattern)정방향 부정 조회는 패턴과 일치하지 않는 문자열의 시작 부분에 있는 검색 문자열과 일치합니다. 이는 가져오지 않는 일치입니다. 즉, 나중에 사용하기 위해 일치 항목을 가져올 필요가 없습니다. 예를 들어, "Windows(?!95|98|NT|2000)"는 "Windows3.1"의 "Windows"와 일치할 수 있지만 "Windows2000"의 "Windows"와 일치할 수는 없습니다. (?<=pattern)역방향 긍정 사전 확인은 정방향 긍정 사전 확인과 유사하지만 방향이 반대입니다. 예를 들어, "(?<=95|98|NT|2000)Windows"는 "2000Windows"의 "Windows"와 일치할 수 있지만 "3.1Windows"의 "Windows"와 일치할 수는 없습니다. (?역방향 네거티브 미리보기는 순방향 네거티브 미리보기와 유사하지만 반대 방향입니다. 예를 들어, "(?x|y은 x 또는 y와 일치합니다. 예를 들어 "z|food"는 "z" 또는 "food"와 일치합니다. "(z|f)ood"는 "zood" 또는 "food"와 일치합니다. [xyz]캐릭터 컬렉션. 포함된 문자 중 하나와 일치합니다. 예를 들어, "[abc]"는 "plain"의 "a"와 일치합니다.
정규 문자정규 해석
다음 문자를 특수 문자, 리터럴 문자, 역참조 또는 8진수 이스케이프 문자로 표시합니다. 예를 들어, "n"은 문자 "n"과 일치합니다. "\n"은 개행 문자와 일치합니다. 시퀀스 "\"는 ""와 일치하고 "("는 "("와 일치합니다.
^은 입력 문자열의 시작 부분과 일치합니다. RegExp 개체의 Multiline 속성이 설정된 경우 ^는 "n" 또는 "n"과도 일치합니다. "r " after ".
$은 입력 문자열의 끝과 일치합니다. RegExp 개체의 Multiline 속성이 설정된 경우 $는 "n" 또는 "r" 앞의 위치와도 일치합니다.
* 이전 하위 표현식과 0회 이상 일치합니다. 예를 들어, zo*는 "z"와 일치하며 *는 {0,}와 동일합니다.
[^xyz]부정 문자 모음입니다. 포함되지 않은 모든 문자와 일치합니다. 예를 들어, "[^abc]"는 "plain"의 "plin"과 일치합니다.
[a-z]문자 범위. 지정된 범위 내의 모든 문자와 일치합니다. 예를 들어, "[a-z]"는 "a"부터 "z"까지의 범위에 있는 모든 소문자 알파벳 문자와 일치합니다. 참고: 하이픈이 문자 그룹 내부에 있고 두 문자 사이에 있는 경우에만 문자 범위를 나타낼 수 있습니다. 문자 그룹의 시작 부분에 나타나면 하이픈 자체만 나타낼 수 있습니다.
[^a-z ] 음수 문자 범위. 지정된 범위 내에 없는 모든 문자와 일치합니다. 예를 들어, "[^a-z]"는 "a"부터 "z"까지의 범위에 없는 모든 문자와 일치합니다.
b은 단어와 공백 사이의 위치를 ​​나타내는 단어 경계와 일치합니다. 예를 들어, "erb"는 "never"의 "er"와 일치할 수 있지만 "동사"의 "er"와는 일치하지 않습니다.
B은 단어가 아닌 경계와 일치합니다. "erB"는 "동사"의 "er"와 일치할 수 있지만 "never"의 "er"는 일치하지 않습니다.
cx은 x로 지정된 제어 문자와 일치합니다. 예를 들어, cM은 Control-M 또는 캐리지 리턴 문자와 일치합니다. x 값은 A-Z 또는 a-z 중 하나여야 합니다. 그렇지 않으면 c를 리터럴 "c" 문자로 처리합니다.
d은 숫자와 일치합니다. [0-9]와 동일합니다.
D은 숫자가 아닌 문자와 일치합니다. [^0-9]와 동일합니다.
f은 폼 피드와 일치합니다. x0c 및 cL과 동일합니다.
n은 개행 문자와 일치합니다. x0a 및 cJ와 동일합니다.
r은 캐리지 리턴 문자와 일치합니다. x0d 및 cM과 동일합니다.
s은 공백, 탭, 양식 피드 등을 포함한 모든 공백 문자와 일치합니다. [fnrtv]와 동일합니다.
S은 공백이 아닌 모든 문자와 일치합니다. [^ fnrtv]와 동일합니다.
t은 탭 문자와 일치합니다. x09 및 cI와 동일합니다.
v은 세로 탭 문자와 일치합니다. x0b 및 cK와 동일합니다.
w은 밑줄을 포함한 모든 단어 문자와 일치합니다. "[A-Za-z0-9_]"와 동일합니다.
W은 단어가 아닌 문자와 일치합니다. "[^A-Za-z0-9_]"와 동일합니다.
xn은 n과 일치합니다. 여기서 n은 16진수 이스케이프 값입니다. 16진수 이스케이프 값은 정확히 두 자리 길이여야 합니다. 예를 들어 "x41"은 "A"와 일치합니다. "x041"은 "x04&1"과 동일합니다. ASCII 인코딩은 정규식에서 사용할 수 있습니다.
num은 num과 일치합니다. 여기서 num은 양의 정수입니다. 획득한 일치 항목에 대한 참조입니다. 예를 들어, "(.)1"은 두 개의 연속된 동일한 문자와 일치합니다.
n8진수 이스케이프 값 또는 역참조를 식별합니다. n 앞에 가져온 n개 이상의 하위 표현식이 있으면 n은 역방향 참조입니다. 그렇지 않고 n이 8진수(0-7)이면 n은 8진수 이스케이프 값입니다.
nm8진수 이스케이프 값 또는 역참조를 식별합니다. nm 앞에 최소한 nm get 하위 표현식이 오면 nm은 역방향 참조입니다. nm 앞에 최소한 n의 획득이 있으면 n은 역방향 참조이고 그 뒤에는 리터럴 m이 옵니다. 이전 조건 중 어느 것도 충족되지 않고 n과 m이 모두 8진수(0-7)인 경우 nm은 8진수 이스케이프 값 nm과 일치합니다.
nmln이 8진수(0-7)이고 m과 l이 모두 8진수(0-7)인 경우 8진수 이스케이프 값 nml과 일치합니다.
un은 n과 일치합니다. 여기서 n은 4개의 16진수 숫자로 표시되는 유니코드 문자입니다. 예를 들어, u00A9는 저작권 기호(©)와 일치합니다.

上表是正则表达式比较全面的解释,而商标中的正则字符都有特殊含义,已经不再代表原字符含义。如正则表达式中“+”不代表加号,而是代表匹配一次或多次。而如果想要让“+”表示加号,则需要在其前面加上“\”转义,也就是用“\+”表示加号。

1+1=2  正则表达式是: 1\+1=2
而正则表达式 1+1=2 可以代表,多个1=2,即:
11=2     正则表达式:1+1=2
111=2    正则表达式:1+1=2
1111=2   正则表达式:1+1=2
……
로그인 후 복사

也就是说所有正则字符都有特定含义,如果需要再用来表示原字符含义,就需要在前面加“\”转义,即使非正则字符,用“\”转义也是没有问题的。

1+1=2  正则表达式也可以是: \1\+\1\=\2
로그인 후 복사

对所有字符都转义,但是这种不建议使用。

而正则表达式必须要使用定界符包围起来,在Javascript中定界符是“/”,而在PHP中,比较常见的是用“/”定界,也可以用“#”定界,而且外面还需要用引号包围起来。

如果正则表达式包含这些定界符,您就需要对这些字符进行转义。

PHP 正则表达式定界符

大多数语言的正则表达式都是由“/”作为定界符的,而在PHP中,还可以使用“#”定界,如果字符串中包含大量“/”字符,在使用“/”定界的时候,就需要对这些“/”转义,而使用“#”就不需要转义,更简洁。

<?php
$weigeti=&#39;W3CSchool 在线教程的网址是 http://e.jb51.net/ ,你能把这个网址替换成正确的网址吗?&#39;;
// 上面的要求就是把http://e.jb51.net/ 替换成 http://e.jb51.net/w3c/ 
// . : - 都是正则符号,所以需要转义,而 / 是定界符,如果字符串中包含 / 定界符,就需要转义
echo preg_replace(&#39;/http\:\/\/www\.jb51\.net\//&#39;,&#39;http://e.jb51.net/w3c/&#39;,$weigeti);
// 在 #作为定界符,/ 就不再是定界符的含义,就不需要转义了。
echo preg_replace(&#39;#http\://www\.jb51\.net/#&#39;,&#39;http://e.jb51.net/w3c/&#39;,$weigeti);
//上面两条输出结果都一样,【W3CSchool 在线教程的网址是 http://e.jb51.net/w3c/ ,你能把这个网址替换成正确的网址吗?】
?>
로그인 후 복사

通过上面的两条PHP 正则替换代码我们可以发现,如果正则语句中包含大量“/”,无论使用“/” 还是 “#”做定界符都是可以的,但是使用“#”能让代码看起来更简洁。但是E维科技建议您还是保持使用“/”作为定界符,因为在Javascript等语言中,只能使用“/”作为定界符,这样写起来可以形成习惯,贯通于其他语言中。

PHP 正则表达式修饰符

修饰符被放在PHP正则表达式定界符“/”尾部,在正则表达式尾部引号之前。

i 忽略大小写,匹配不考虑大小写
m 多行独立匹配,如果字符串不包含[\n]等换行符就和普通正则一样。
s 设置正则符号 . 可以匹配换行符[\n],如果没有设置,正则符号.不能匹配换行符\n。
x 忽略没有转义的空格
e eval() 对匹配后的元素执行函数。
A 前置锚定,约束匹配仅从目标字符串开始搜索
D 锁定$作为结尾,如果没有D,如果字符串包含[\n]等换行符,$依旧依旧匹配换行符。如果设置了修饰符m,修饰符D 就会被忽略。
S 对非锚定的匹配进行分析
U 非贪婪,如果在正则字符量词后加“?”,就可以恢复贪婪
X 打开与perl 不兼容附件
u 强制字符串为UTF-8编码,一般在非UTF-8编码的文档中才需要这个。建议UTF-8环境中不要使用这个,据E维科技调查使用这个会有一个Bug。
로그인 후 복사

如果您熟悉Javascript 的正则表达式,或许一定熟悉Javascript 正则表达式的修饰符“g”,代表匹配所有符合条件的元素。而在PHP 正则替换中,是匹配所有符号条件的元素,所以不存在Javascript 修饰符“g”。

PHP 正则中文和忽略大小写PHP preg_replace() 是区分大小写的,同时只能匹配ASCII编码内的字符串,如果需要匹配不区分大小写和中文等字符需要添加相应的修饰符 i 或 u。

<?php
$weigeti=&#39;php中文网 在线教程网址://www.php.cn/&#39;;
echo preg_replace(&#39;/php中文网/&#39;,&#39;php&#39;,$weigeti);
//大小写不同,输出【php 在线教程网址://www.php.cn/】
echo preg_replace(&#39;/php中文网/i&#39;,&#39;php&#39;,$weigeti);
//忽略大小写,执行替换输出【php 在线教程网址:http://e.php.cn/】
echo preg_replace(&#39;/网址/u&#39;,&#39;&#39;,$weigeti);
//强制 UTF-8中文,执行替换,输出【PHP中文网 在线教程://www.php.cn/】
?>
로그인 후 복사

大小写和中文在PHP中都是敏感的,但是在Javascript正则中,只对大小写敏感,忽略大小写也是通过修饰符 i 作用的,但是Javascript 不需要告知是否是UTF-8中文等特殊字符,直接可以匹配中文。

PHP 正则换行符实例

PHP 正则表达式在遇到换行符时,会将换行符当做字符串中间一个普通字符。而通用符号.不能匹配\n,所以遇到带有换行符的字符串正则会有很多要点。

<?php
$weigeti="php.cn\nIS\nLOVING\nYOU";
// 想要把上面$weigeti 替换成php.cn
echo preg_replace(&#39;/^[A-Z].*[A-Z]$/&#39;,&#39;&#39;,$weigeti);
// 这个正则表达式是,匹配只包含\w的元素,$weigeti 是以V开头,符合[A-Z],而且结尾是U,也符合[A-Z]。.无法匹配\n
// 输出【jb51.net IS LOVEING YOU】
echo preg_replace(&#39;/^[A-Z].*[A-Z]$/s&#39;,&#39;&#39;,$weigeti);
// 这个用修饰符s,也就是 . 可以匹配 \n 了,所以整句匹配,输出空
// 输出【】
echo preg_replace(&#39;/^[A-Z].*[A-Z]$/m&#39;,&#39;&#39;,$weigeti);
// 这里使用了修饰符,将\n作为多行独立匹配。也就等价于:
/* 
$preg_m=preg_replace(&#39;/^[A-Z].*[A-Z]$/m&#39;,&#39;&#39;,$weigeti);
$p=&#39;/^[A-Z].*[A-Z]$/&#39;;
$a=preg_replace($p,&#39;&#39;,&#39;php.cn&#39;);
$b=preg_replace($p,&#39;&#39;,&#39;IS&#39;);
$c=preg_replace($p,&#39;&#39;,&#39;LOVING&#39;);
$d=preg_replace($p,&#39;&#39;,&#39;YOU&#39;);
$preg_m === $a.$b.$c.$d;
*/
// 输出【php.cn】
?>
로그인 후 복사

以后您在使用PHP 抓取某个网站内容,并用正则批量替换的时候,总无法避免忽略获取的内容包含换行符,所以在使用正则替换的时候一定要注意。

PHP 正则匹配执行函数PHP 正则替换可以使用一个修饰符e,代表 eval() 来执行匹配后的内容某个函数。

<?php
$weigeti=&#39;W3CSchool 在线教程网址://www.jb51.net ,你Jbzj!了吗?&#39;;
// 将上面网址转为小写
echo preg_replace(&#39;/(http\:[\/\w\.\-]+\/)/e&#39;,&#39;strtolower("$1")&#39;,$weigeti);
// 使用修饰符e之后,就可以对匹配的网址执行PHP 函数 strtolower() 了
// 输出 【W3CSchool 在线教程网址://www.jb51.net ,你Jbzj!了吗?】
?>
로그인 후 복사

根据上面代码,尽管匹配后的函数 strtolower() 在引号内,但是依旧会被eval()执行。

正则替换匹配变量向后引用

如果您熟悉Javascript,一定对$1 $2 $3 …… 等向后引用比较熟悉,而在 PHP 中这些也可以被当作向后引用参数。而在PHP中,还可以使用 \1 \\1 来表示向后引用。

向后引用的概念就是匹配一个大片段,这个正则表达式内部又被用括号切割成若干小匹配元素,那么每个匹配元素就被按照小括号序列用向后引用代替。

<?php
$weigeti=&#39;W3CSchool 在线教程网址://www.jb51.net ,你Jbzj!了吗?&#39;;
echo preg_replace(&#39;/.+(http\:[\w\-\/\.]+\/)[^\w\-\!]+([\w\-\!]+).+/&#39;,&#39;$1&#39;,$weigeti);
echo preg_replace(&#39;/.+(http\:[\w\-\/\.]+\/)[^\w\-\!]+([\w\-\!]+).+/&#39;,&#39;\1&#39;,$weigeti);
echo preg_replace(&#39;/.+(http\:[\w\-\/\.]+\/)[^\w\-\!]+([\w\-\!]+).+/&#39;,&#39;\\1&#39;,$weigeti);
// 上面三个都是输出 【//www.jb51.net】
echo preg_replace(&#39;/^(.+)网址:(http\:[\w\-\/\.]+\/)[^\w\-\!]+([\w\-\!]+).+$/&#39;,&#39;栏目:$1<br>网址:$2<br>商标:$3&#39;,$weigeti);
/*
栏目:W3CSchool 在线教程
网址://www.jb51.net
商标:Jbzj!
*/
// 括号中括号,外面括号先计数
echo preg_replace(&#39;/^((.+)网址:(http\:[\w\-\/\.]+\/)[^\w\-\!]+([\w\-\!]+).+)$/&#39;,&#39;原文:$1<br>栏目:$2<br>网址:$3<br>商标:$4&#39;,$weigeti);
/*
原文:W3CSchool 在线教程网址://www.jb51.net ,你Jbzj!了吗?
栏目:W3CSchool 在线教程
网址://www.jb51.net
商标:Jbzj!
*/
?>
로그인 후 복사

以上就是本文的全部内容,希望对大家的学习有所帮助,更多相关内容请关注PHP中文网!

相关推荐:

关于php中str_replace替换漏洞的分析

如何通过php获取随机数组列表

위 내용은 조건에 맞는 모든 문자열을 정기적으로 교체하는 PHP의 preg_replace() 메서드에 대해의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

관련 라벨:
원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿