찾다
백엔드 개발PHP 튜토리얼正则表达式经验谈_PHP教程

正则表达式经验谈_PHP教程

Jul 13, 2016 pm 05:35 PM
기본가독성존재하다제안개발하다정기적인~의표현

本文的建议主要着眼于正则表达式的可读性,在开发中养成这些习惯,你将会更加清晰的考虑设计和表达式的结构,这将有助于减少bug和代码的维护,如果你自己就是这个代码的维护者你将倍感轻松。大家可以自己看看,在自己实际使用的过程中注意正则表达式的这些经验。
正则表达式难于书写、难于阅读、难于维护,经常错误匹配意料不到的文本或者错过了有效的文本,这些问题都是由正则表达式的表现和能力引起的。每个元字符(metacharacter)的能力和细微差别组合在一起,使得代码不借助于智力技巧就无法解释。
许多包含一定特性的工具使阅读和编写正则表达式变得容易了,但是它们又很不符合习惯。对于很多程序员来说,书写正则表达式就是一种魔法艺术。他们坚持自己所知道的特征并持有绝对乐观的态度。如果你愿意采用本文所探讨的五个习惯,你将可以让你设计的正则表达式经受的住反复试验。
本文将使用Perl、PHP和Python语言作为代码示例,但是本文的建议几乎适用于任何替换表达式(regex)的执行。

一、使用空格和注释

对于大部分程序员来说,在一个正则表达式环境里使用空格和缩进排列都不成问题,如果他们没有这么做一定会被同行甚至外行人士看笑话。几乎每个人都知道把代码挤在一行会难于阅读、书写和维护。对于正则表达式又有什么不同呢?
大部分替换表达式工具都具有扩展的空格特性,这允许程序员把他们的正则表达式扩展为多行,并在每一行结尾加上注释。为什么只有少部分程序员利用这个特性呢?Perl 6的正则表达式默认就是扩展空格的模式。不要再让语言替你默认扩展空格了,自己主动利用吧。
记住扩展空格的窍门之一就是让正则表达式引擎忽略扩展空格。这样如果你需要匹配空格,你就不得不明确说明。
在Perl语言里面,在正则表达式的结尾加上x,这样“m/foo bar/”变为如下形式:

m/
foo
 
bar
/x

在PHP语言里面,在正则表达式的结尾加上x,这样“"/foo bar/"”变为如下形式:

"/
foo
 
bar
/x"

在Python语言里面,传递模式修饰参数“re.VERBOSE”得到编译函数如下:

pattern = r
foo
 
bar

regex = re.compile(pattern, re.VERBOSE)

处理更加复杂的正则表达式时,空格和注释就更能体现出其重要性。假设下面的正则表达式用于匹配美国的电话号码:

(?d{3})? ?d{3}[-.]d{4}

这个正则表达式匹配电话号码如“(314)555-4000”的形式,你认为这个正则表达式是否匹配“314-555-4000”或者“555- 4000”呢?答案是两种都不匹配。写上这么一行代码隐蔽了缺点和设计结果本身,电话区号是需要的,但是正则表达式在区号和前缀之间缺少一个分隔符号的说明。
把这一行代码分成几行并加上注释将把缺点暴露无疑,修改起来显然更容易一些。
在Perl语言里面应该是如下形式:

/
(? # 可选圆括号
d{3} # 必须的电话区号
)? # 可选圆括号
[-s.]? # 分隔符号可以是破折号、空格或者句点
d{3} # 三位数前缀
[-.] # 另一个分隔符号
d{4} # 四位数电话号码
/x

改写过的正则表达式现在在电话区号后有一个可选择的分隔符号,这样它应该是匹配“314-555-4000”的,然而电话区号还是必须的。另一个程序员如果需要把电话区号变为可选项则可以迅速看出它现在不是可选的,一个小小的改动就可以解决这个问题。

二、书写测试

一共有三个层次的测试,每一层为你的代码加上一层可靠性。首先,你需要认真想想你需要匹配什么代码以及你是否能够处理错误匹配。其次,你需要利用数据实例来测试正则表达式。最后,你需要正式通过一个测试小组的测试。
决定匹配什么其实就是在匹配错误结果和错过正确结果之间寻求一个平衡点。如果你的正则表达式过于严格,它将会错过一些正确匹配;如果它过于宽松,它将会产生一个错误匹配。一旦某个正则表达式发放到实际代码当中,你可能不会两者都注意到。考虑一下上面电话号码的例子,它将会匹配“800-555-4000 = -5355”。错误的匹配其实很难发现,所以提前规划做好测试是很重要的。
还是使用电话号码的例子,如果你在Web表单里面确认一个电话号码,你可能只要满足于任何格式的十位数字。但是,如果你想从大量文本里面分离电话号码,你可能需要很认证的排除不符合要求的错误匹配。
在考虑你想匹配的数据的时候,写下一些案例情况。针对案例情况写下一些代码来测试你的正则表达式。任何复杂的正则表达式都最好写个小程序测试一下,可以采用下面的具体形式。
在Perl语言里面:

#!/usr/bin/perl

my @tests = ( "314-555-4000",
"800-555-4400",
"(314)555-4000",
"314.555.4000",
"555-4000",
"aasdklfjklas",
"1234-123-12345"
);

foreach my $test (@tests) {
if ( $test =~ m/
(? # 可选圆括号
d{3} # 必须的电话区号
)? # 可选圆括号
[-s.]? # 分隔符号可以是破折号、空格或者句点
d{3} # 三位数前缀
[-s.] # 另一个分隔符号
d{4} # 四位数电话号码
/x ) {
print "Matched on $test ";
}
else {
print "Failed match on $test ";
}
}

在PHP语言里面:

<?php
$tests = array( "314-555-4000",

"800-555-4400",
"(314)555-4000",
"314.555.4000",
"555-4000",
"aasdklfjklas",
"1234-123-12345" );

$regex = "/
(? # 可选圆括号
d{3} # 必须的电话区号
)? # 可选圆括号
[-s.]? # 分隔符号可以是破折号、空格或者句点
d{3} # 三位数前缀
[-s.] # 另一个分隔符号
d{4} # 四位数电话号码
/x";

foreach ($tests as $test) {
if (preg_match($regex, $test)) {
echo "Matched on $test
;";
}
else {
echo "Failed match on $test
;";
}
}
?>;

在Python语言里面:

import re

tests = ["314-555-4000",
"800-555-4400",
"(314)555-4000",
"314.555.4000",
"555-4000",
"aasdklfjklas",
"1234-123-12345"
]

pattern = r
(? # 可选圆括号
d{3} # 必须的电话区号
)? # 可选圆括号
[-s.]? # 分隔符号可以是破折号、空格或者句点
d{3} # 三位数前缀
[-s.] # 另一个分隔符号
d{4} # 四位数电话号码

regex = re.compile( pattern, re.VERBOSE ) for test in tests:
if regex.match(test):
print "Matched on", test, " "
else:
print "Failed match on", test, " "

运行测试代码将会发现另一个问题:它匹配“1234-123-12345”。
理论上,你需要整合整个程序所有的测试到一个测试小组里面。即使你现在还没有测试小组,你的正则表达式测试也会是一个小组的良好基础,现在正是开始创建的好机会。即使现在还不是创建的合适时间,你也应该在每次修改以后运行测试一下正则表达式。这里花费一小段时间将会减少你很多麻烦事。

三、为交替操作分组

交替操作符号( )的优先级很低,这意味着它经常交替超过程序员所设计的那样。比如,从文本里面抽取Email地址的正则表达式可能如下:

^CC: To:(.*)

上面的尝试是不正确的,但是这个bug往往不被注意。上面代码的意图是找到“CC:”或者“To:”开始的文本,然后在这一行的后面部分提取Email地址。
不幸的是,如果某一行中间出现“To:”,那么这个正则表达式将捕获不到任何以“CC:”开始的一行,而是抽取几个随机的文本。坦白的说,正则表达式匹配 “CC:”开始的一行,但是什么都捕获不到;或者匹配任何包含“To:”的一行,但是把这行的剩余文本都捕获了。通常情况下,这个正则表达式会捕获大量 Email地址,所有没有人会注意这个bug。
如果要符合实际意图,那么你应该加入括号说明清楚,正则表达式如下:

(^CC:) (To:(.*))

如果真正意图是捕获以“CC:”或者“To:”开始的文本行的剩余部分,那么正确的正则表达式如下:

^(CC: To:)(.*)

这是一个普遍的不完全匹配的bug,如果你养成为交替操作分组的习惯,你就会避免这个错误。

四、使用宽松数量词

很多程序员避免使用宽松数量词比如“*?”、“+?”和“??”,即使它们会使这个表达式易于书写和理解。
宽松数量词可以尽可能少的匹配文本,这样有助于完全匹配的成功。如果你写了“foo(.*?)bar”,那么数量词将在第一次遇到“bar”时就停止匹配,而不是在最后一次。如果你希望从“foo###bar+++bar”中捕获“###”,这一点就很重要。一个严格数量词将捕获“###bar++ +”。;),这将会带来很*烦。如果你使用了宽松数量词,你只要花上很少的时间组装字符种类就能产生新的正则表达式。
在你知道你要捕获文本的环境结构时,宽松数量词是具有很大价值的。

五、利用可用分界符

Perl 和PHP语言常常使用左斜线(/)来标志一个正则表达式的开头和结尾,Python语言使用一组引号来标志开头和结尾。如果在Perl和PHP中坚持使用左斜线,你将要避免表达式中的任何斜线;如果在Python中使用引号,你将要避免使用反斜线()。选择不同的分界符或引号可以允许你避免一半的正则表达式。这将使得表达式易于阅读,减少由于忘记避免符号而潜在的bug。
Perl和PHP语言允许使用任何非数字和空格字符作为分界符。如果你切换到一个新的分界符,在匹配URL或HTML标志(如“http://”或“<br/>;”)时,你就可以避免漏掉左斜线了。
例如,“/http://(S)*/”可以写为“#http://(S)*#”。
通用分界符是“#”、“!”和“ ”。如果你要使用方括号、尖括号或者花括号,只要保持前后配对出现就可以了。

www.bkjia.comtruehttp://www.bkjia.com/PHPjc/508305.htmlTechArticle本文的建议主要着眼于正则表达式的可读性,在开发中养成这些习惯,你将会更加清晰的考虑设计和表达式的结构,这将有助于减少bug和代...

성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
PHP의 현재 상태 : 웹 개발 동향을 살펴보십시오PHP의 현재 상태 : 웹 개발 동향을 살펴보십시오Apr 13, 2025 am 12:20 AM

PHP는 현대 웹 개발, 특히 컨텐츠 관리 및 전자 상거래 플랫폼에서 중요합니다. 1) PHP는 Laravel 및 Symfony와 같은 풍부한 생태계와 강력한 프레임 워크 지원을 가지고 있습니다. 2) Opcache 및 Nginx를 통해 성능 최적화를 달성 할 수 있습니다. 3) PHP8.0은 성능을 향상시키기 위해 JIT 컴파일러를 소개합니다. 4) 클라우드 네이티브 애플리케이션은 Docker 및 Kubernetes를 통해 배포되어 유연성과 확장 성을 향상시킵니다.

PHP 대 기타 언어 : 비교PHP 대 기타 언어 : 비교Apr 13, 2025 am 12:19 AM

PHP는 특히 빠른 개발 및 동적 컨텐츠를 처리하는 데 웹 개발에 적합하지만 데이터 과학 및 엔터프라이즈 수준의 애플리케이션에는 적합하지 않습니다. Python과 비교할 때 PHP는 웹 개발에 더 많은 장점이 있지만 데이터 과학 분야에서는 Python만큼 좋지 않습니다. Java와 비교할 때 PHP는 엔터프라이즈 레벨 애플리케이션에서 더 나빠지지만 웹 개발에서는 더 유연합니다. JavaScript와 비교할 때 PHP는 백엔드 개발에서 더 간결하지만 프론트 엔드 개발에서는 JavaScript만큼 좋지 않습니다.

PHP vs. Python : 핵심 기능 및 기능PHP vs. Python : 핵심 기능 및 기능Apr 13, 2025 am 12:16 AM

PHP와 Python은 각각 고유 한 장점이 있으며 다양한 시나리오에 적합합니다. 1.PHP는 웹 개발에 적합하며 내장 웹 서버 및 풍부한 기능 라이브러리를 제공합니다. 2. Python은 간결한 구문과 강력한 표준 라이브러리가있는 데이터 과학 및 기계 학습에 적합합니다. 선택할 때 프로젝트 요구 사항에 따라 결정해야합니다.

PHP : 웹 개발의 핵심 언어PHP : 웹 개발의 핵심 언어Apr 13, 2025 am 12:08 AM

PHP는 서버 측에서 널리 사용되는 스크립팅 언어이며 특히 웹 개발에 적합합니다. 1.PHP는 HTML을 포함하고 HTTP 요청 및 응답을 처리 할 수 ​​있으며 다양한 데이터베이스를 지원할 수 있습니다. 2.PHP는 강력한 커뮤니티 지원 및 오픈 소스 리소스를 통해 동적 웹 컨텐츠, 프로세스 양식 데이터, 액세스 데이터베이스 등을 생성하는 데 사용됩니다. 3. PHP는 해석 된 언어이며, 실행 프로세스에는 어휘 분석, 문법 분석, 편집 및 실행이 포함됩니다. 4. PHP는 사용자 등록 시스템과 같은 고급 응용 프로그램을 위해 MySQL과 결합 할 수 있습니다. 5. PHP를 디버깅 할 때 error_reporting () 및 var_dump ()와 같은 함수를 사용할 수 있습니다. 6. 캐싱 메커니즘을 사용하여 PHP 코드를 최적화하고 데이터베이스 쿼리를 최적화하며 내장 기능을 사용하십시오. 7

PHP : 많은 웹 사이트의 기초PHP : 많은 웹 사이트의 기초Apr 13, 2025 am 12:07 AM

PHP가 많은 웹 사이트에서 선호되는 기술 스택 인 이유에는 사용 편의성, 강력한 커뮤니티 지원 및 광범위한 사용이 포함됩니다. 1) 배우고 사용하기 쉽고 초보자에게 적합합니다. 2) 거대한 개발자 커뮤니티와 풍부한 자원이 있습니다. 3) WordPress, Drupal 및 기타 플랫폼에서 널리 사용됩니다. 4) 웹 서버와 밀접하게 통합하여 개발 배포를 단순화합니다.

과대 광고 : 오늘 PHP의 역할을 평가합니다과대 광고 : 오늘 PHP의 역할을 평가합니다Apr 12, 2025 am 12:17 AM

PHP는 현대적인 프로그래밍, 특히 웹 개발 분야에서 강력하고 널리 사용되는 도구로 남아 있습니다. 1) PHP는 사용하기 쉽고 데이터베이스와 완벽하게 통합되며 많은 개발자에게 가장 먼저 선택됩니다. 2) 동적 컨텐츠 생성 및 객체 지향 프로그래밍을 지원하여 웹 사이트를 신속하게 작성하고 유지 관리하는 데 적합합니다. 3) 데이터베이스 쿼리를 캐싱하고 최적화함으로써 PHP의 성능을 향상시킬 수 있으며, 광범위한 커뮤니티와 풍부한 생태계는 오늘날의 기술 스택에 여전히 중요합니다.

PHP의 약한 참고 자료는 무엇이며 언제 유용합니까?PHP의 약한 참고 자료는 무엇이며 언제 유용합니까?Apr 12, 2025 am 12:13 AM

PHP에서는 약한 참조가 약한 회의 클래스를 통해 구현되며 쓰레기 수집가가 물체를 되 찾는 것을 방해하지 않습니다. 약한 참조는 캐싱 시스템 및 이벤트 리스너와 같은 시나리오에 적합합니다. 물체의 생존을 보장 할 수 없으며 쓰레기 수집이 지연 될 수 있음에 주목해야합니다.

PHP의 __invoke 마법 방법을 설명하십시오.PHP의 __invoke 마법 방법을 설명하십시오.Apr 12, 2025 am 12:07 AM

\ _ \ _ 호출 메소드를 사용하면 객체를 함수처럼 호출 할 수 있습니다. 1. 객체를 호출 할 수 있도록 메소드를 호출하는 \ _ \ _ 정의하십시오. 2. $ obj (...) 구문을 사용할 때 PHP는 \ _ \ _ invoke 메소드를 실행합니다. 3. 로깅 및 계산기, 코드 유연성 및 가독성 향상과 같은 시나리오에 적합합니다.

See all articles

핫 AI 도구

Undresser.AI Undress

Undresser.AI Undress

사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover

AI Clothes Remover

사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool

Undress AI Tool

무료로 이미지를 벗다

Clothoff.io

Clothoff.io

AI 옷 제거제

AI Hentai Generator

AI Hentai Generator

AI Hentai를 무료로 생성하십시오.

인기 기사

R.E.P.O. 에너지 결정과 그들이하는 일 (노란색 크리스탈)
3 몇 주 전By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. 최고의 그래픽 설정
3 몇 주 전By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. 아무도들을 수없는 경우 오디오를 수정하는 방법
3 몇 주 전By尊渡假赌尊渡假赌尊渡假赌
WWE 2K25 : Myrise에서 모든 것을 잠금 해제하는 방법
4 몇 주 전By尊渡假赌尊渡假赌尊渡假赌

뜨거운 도구

맨티스BT

맨티스BT

Mantis는 제품 결함 추적을 돕기 위해 설계된 배포하기 쉬운 웹 기반 결함 추적 도구입니다. PHP, MySQL 및 웹 서버가 필요합니다. 데모 및 호스팅 서비스를 확인해 보세요.

메모장++7.3.1

메모장++7.3.1

사용하기 쉬운 무료 코드 편집기

MinGW - Windows용 미니멀리스트 GNU

MinGW - Windows용 미니멀리스트 GNU

이 프로젝트는 osdn.net/projects/mingw로 마이그레이션되는 중입니다. 계속해서 그곳에서 우리를 팔로우할 수 있습니다. MinGW: GCC(GNU Compiler Collection)의 기본 Windows 포트로, 기본 Windows 애플리케이션을 구축하기 위한 무료 배포 가능 가져오기 라이브러리 및 헤더 파일로 C99 기능을 지원하는 MSVC 런타임에 대한 확장이 포함되어 있습니다. 모든 MinGW 소프트웨어는 64비트 Windows 플랫폼에서 실행될 수 있습니다.

PhpStorm 맥 버전

PhpStorm 맥 버전

최신(2018.2.1) 전문 PHP 통합 개발 도구

SublimeText3 중국어 버전

SublimeText3 중국어 버전

중국어 버전, 사용하기 매우 쉽습니다.