正则表达式经验谈_PHP教程
本文的建议主要着眼于正则表达式的可读性,在开发中养成这些习惯,你将会更加清晰的考虑设计和表达式的结构,这将有助于减少bug和代码的维护,如果你自己就是这个代码的维护者你将倍感轻松。大家可以自己看看,在自己实际使用的过程中注意正则表达式的这些经验。 一、使用空格和注释 对于大部分程序员来说,在一个正则表达式环境里使用空格和缩进排列都不成问题,如果他们没有这么做一定会被同行甚至外行人士看笑话。几乎每个人都知道把代码挤在一行会难于阅读、书写和维护。对于正则表达式又有什么不同呢? m/ 在PHP语言里面,在正则表达式的结尾加上x,这样“"/foo bar/"”变为如下形式: "/ 在Python语言里面,传递模式修饰参数“re.VERBOSE”得到编译函数如下: pattern = r 处理更加复杂的正则表达式时,空格和注释就更能体现出其重要性。假设下面的正则表达式用于匹配美国的电话号码: (?d{3})? ?d{3}[-.]d{4} 这个正则表达式匹配电话号码如“(314)555-4000”的形式,你认为这个正则表达式是否匹配“314-555-4000”或者“555- 4000”呢?答案是两种都不匹配。写上这么一行代码隐蔽了缺点和设计结果本身,电话区号是需要的,但是正则表达式在区号和前缀之间缺少一个分隔符号的说明。 / 改写过的正则表达式现在在电话区号后有一个可选择的分隔符号,这样它应该是匹配“314-555-4000”的,然而电话区号还是必须的。另一个程序员如果需要把电话区号变为可选项则可以迅速看出它现在不是可选的,一个小小的改动就可以解决这个问题。 二、书写测试 一共有三个层次的测试,每一层为你的代码加上一层可靠性。首先,你需要认真想想你需要匹配什么代码以及你是否能够处理错误匹配。其次,你需要利用数据实例来测试正则表达式。最后,你需要正式通过一个测试小组的测试。 #!/usr/bin/perl my @tests = ( "314-555-4000", foreach my $test (@tests) { 在PHP语言里面: <?php "800-555-4400", $regex = "/ foreach ($tests as $test) { 在Python语言里面: import re tests = ["314-555-4000", pattern = r regex = re.compile( pattern, re.VERBOSE ) for test in tests: 运行测试代码将会发现另一个问题:它匹配“1234-123-12345”。 三、为交替操作分组 交替操作符号( )的优先级很低,这意味着它经常交替超过程序员所设计的那样。比如,从文本里面抽取Email地址的正则表达式可能如下: ^CC: To:(.*) 上面的尝试是不正确的,但是这个bug往往不被注意。上面代码的意图是找到“CC:”或者“To:”开始的文本,然后在这一行的后面部分提取Email地址。 (^CC:) (To:(.*)) 如果真正意图是捕获以“CC:”或者“To:”开始的文本行的剩余部分,那么正确的正则表达式如下: ^(CC: To:)(.*) 这是一个普遍的不完全匹配的bug,如果你养成为交替操作分组的习惯,你就会避免这个错误。 四、使用宽松数量词 很多程序员避免使用宽松数量词比如“*?”、“+?”和“??”,即使它们会使这个表达式易于书写和理解。 五、利用可用分界符 Perl 和PHP语言常常使用左斜线(/)来标志一个正则表达式的开头和结尾,Python语言使用一组引号来标志开头和结尾。如果在Perl和PHP中坚持使用左斜线,你将要避免表达式中的任何斜线;如果在Python中使用引号,你将要避免使用反斜线()。选择不同的分界符或引号可以允许你避免一半的正则表达式。这将使得表达式易于阅读,减少由于忘记避免符号而潜在的bug。
正则表达式难于书写、难于阅读、难于维护,经常错误匹配意料不到的文本或者错过了有效的文本,这些问题都是由正则表达式的表现和能力引起的。每个元字符(metacharacter)的能力和细微差别组合在一起,使得代码不借助于智力技巧就无法解释。
许多包含一定特性的工具使阅读和编写正则表达式变得容易了,但是它们又很不符合习惯。对于很多程序员来说,书写正则表达式就是一种魔法艺术。他们坚持自己所知道的特征并持有绝对乐观的态度。如果你愿意采用本文所探讨的五个习惯,你将可以让你设计的正则表达式经受的住反复试验。
本文将使用Perl、PHP和Python语言作为代码示例,但是本文的建议几乎适用于任何替换表达式(regex)的执行。
大部分替换表达式工具都具有扩展的空格特性,这允许程序员把他们的正则表达式扩展为多行,并在每一行结尾加上注释。为什么只有少部分程序员利用这个特性呢?Perl 6的正则表达式默认就是扩展空格的模式。不要再让语言替你默认扩展空格了,自己主动利用吧。
记住扩展空格的窍门之一就是让正则表达式引擎忽略扩展空格。这样如果你需要匹配空格,你就不得不明确说明。
在Perl语言里面,在正则表达式的结尾加上x,这样“m/foo bar/”变为如下形式:
foo
bar
/x
foo
bar
/x"
foo
bar
regex = re.compile(pattern, re.VERBOSE)
把这一行代码分成几行并加上注释将把缺点暴露无疑,修改起来显然更容易一些。
在Perl语言里面应该是如下形式:
(? # 可选圆括号
d{3} # 必须的电话区号
)? # 可选圆括号
[-s.]? # 分隔符号可以是破折号、空格或者句点
d{3} # 三位数前缀
[-.] # 另一个分隔符号
d{4} # 四位数电话号码
/x
决定匹配什么其实就是在匹配错误结果和错过正确结果之间寻求一个平衡点。如果你的正则表达式过于严格,它将会错过一些正确匹配;如果它过于宽松,它将会产生一个错误匹配。一旦某个正则表达式发放到实际代码当中,你可能不会两者都注意到。考虑一下上面电话号码的例子,它将会匹配“800-555-4000 = -5355”。错误的匹配其实很难发现,所以提前规划做好测试是很重要的。
还是使用电话号码的例子,如果你在Web表单里面确认一个电话号码,你可能只要满足于任何格式的十位数字。但是,如果你想从大量文本里面分离电话号码,你可能需要很认证的排除不符合要求的错误匹配。
在考虑你想匹配的数据的时候,写下一些案例情况。针对案例情况写下一些代码来测试你的正则表达式。任何复杂的正则表达式都最好写个小程序测试一下,可以采用下面的具体形式。
在Perl语言里面:
"800-555-4400",
"(314)555-4000",
"314.555.4000",
"555-4000",
"aasdklfjklas",
"1234-123-12345"
);
if ( $test =~ m/
(? # 可选圆括号
d{3} # 必须的电话区号
)? # 可选圆括号
[-s.]? # 分隔符号可以是破折号、空格或者句点
d{3} # 三位数前缀
[-s.] # 另一个分隔符号
d{4} # 四位数电话号码
/x ) {
print "Matched on $test
";
}
else {
print "Failed match on $test
";
}
}
$tests = array( "314-555-4000",
"(314)555-4000",
"314.555.4000",
"555-4000",
"aasdklfjklas",
"1234-123-12345" );
(? # 可选圆括号
d{3} # 必须的电话区号
)? # 可选圆括号
[-s.]? # 分隔符号可以是破折号、空格或者句点
d{3} # 三位数前缀
[-s.] # 另一个分隔符号
d{4} # 四位数电话号码
/x";
if (preg_match($regex, $test)) {
echo "Matched on $test
;";
}
else {
echo "Failed match on $test
;";
}
}
?>;
"800-555-4400",
"(314)555-4000",
"314.555.4000",
"555-4000",
"aasdklfjklas",
"1234-123-12345"
]
(? # 可选圆括号
d{3} # 必须的电话区号
)? # 可选圆括号
[-s.]? # 分隔符号可以是破折号、空格或者句点
d{3} # 三位数前缀
[-s.] # 另一个分隔符号
d{4} # 四位数电话号码
if regex.match(test):
print "Matched on", test, "
"
else:
print "Failed match on", test, "
"
理论上,你需要整合整个程序所有的测试到一个测试小组里面。即使你现在还没有测试小组,你的正则表达式测试也会是一个小组的良好基础,现在正是开始创建的好机会。即使现在还不是创建的合适时间,你也应该在每次修改以后运行测试一下正则表达式。这里花费一小段时间将会减少你很多麻烦事。
不幸的是,如果某一行中间出现“To:”,那么这个正则表达式将捕获不到任何以“CC:”开始的一行,而是抽取几个随机的文本。坦白的说,正则表达式匹配 “CC:”开始的一行,但是什么都捕获不到;或者匹配任何包含“To:”的一行,但是把这行的剩余文本都捕获了。通常情况下,这个正则表达式会捕获大量 Email地址,所有没有人会注意这个bug。
如果要符合实际意图,那么你应该加入括号说明清楚,正则表达式如下:
宽松数量词可以尽可能少的匹配文本,这样有助于完全匹配的成功。如果你写了“foo(.*?)bar”,那么数量词将在第一次遇到“bar”时就停止匹配,而不是在最后一次。如果你希望从“foo###bar+++bar”中捕获“###”,这一点就很重要。一个严格数量词将捕获“###bar++ +”。;),这将会带来很*烦。如果你使用了宽松数量词,你只要花上很少的时间组装字符种类就能产生新的正则表达式。
在你知道你要捕获文本的环境结构时,宽松数量词是具有很大价值的。
Perl和PHP语言允许使用任何非数字和空格字符作为分界符。如果你切换到一个新的分界符,在匹配URL或HTML标志(如“http://”或“<br/>;”)时,你就可以避免漏掉左斜线了。
例如,“/http://(S)*/”可以写为“#http://(S)*#”。
通用分界符是“#”、“!”和“ ”。如果你要使用方括号、尖括号或者花括号,只要保持前后配对出现就可以了。

핫 AI 도구

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

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

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

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

인기 기사

뜨거운 도구

메모장++7.3.1
사용하기 쉬운 무료 코드 편집기

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

스튜디오 13.0.1 보내기
강력한 PHP 통합 개발 환경

드림위버 CS6
시각적 웹 개발 도구

SublimeText3 Mac 버전
신 수준의 코드 편집 소프트웨어(SublimeText3)

뜨거운 주제











이 AI 지원 프로그래밍 도구는 급속한 AI 개발 단계에서 유용한 AI 지원 프로그래밍 도구를 많이 발굴했습니다. AI 지원 프로그래밍 도구는 개발 효율성을 높이고, 코드 품질을 향상시키며, 버그 발생률을 줄일 수 있습니다. 이는 현대 소프트웨어 개발 프로세스에서 중요한 보조자입니다. 오늘 Dayao는 4가지 AI 지원 프로그래밍 도구(모두 C# 언어 지원)를 공유하겠습니다. 이 도구가 모든 사람에게 도움이 되기를 바랍니다. https://github.com/YSGStudyHards/DotNetGuide1.GitHubCopilotGitHubCopilot은 더 빠르고 적은 노력으로 코드를 작성하는 데 도움이 되는 AI 코딩 도우미이므로 문제 해결과 협업에 더 집중할 수 있습니다. 힘내

세계 최초의 AI 프로그래머 데빈(Devin)이 태어난 지 한 달도 채 안 된 2022년 3월 3일, 프린스턴 대학의 NLP팀은 오픈소스 AI 프로그래머 SWE-에이전트를 개발했습니다. GPT-4 모델을 활용하여 GitHub 리포지토리의 문제를 자동으로 해결합니다. SWE-bench 테스트 세트에서 SWE-agent의 성능은 Devin과 유사하며 평균 93초가 걸리고 문제의 12.29%를 해결합니다. SWE-agent는 전용 터미널과 상호 작용하여 파일 내용을 열고 검색하고, 자동 구문 검사를 사용하고, 특정 줄을 편집하고, 테스트를 작성 및 실행할 수 있습니다. (참고: 위 내용은 원문 내용을 약간 조정한 것이지만 원문의 핵심 정보는 그대로 유지되며 지정된 단어 수 제한을 초과하지 않습니다.) SWE-A

Go 언어 개발 모바일 애플리케이션 튜토리얼 모바일 애플리케이션 시장이 지속적으로 성장함에 따라 점점 더 많은 개발자가 Go 언어를 사용하여 모바일 애플리케이션을 개발하는 방법을 모색하기 시작했습니다. 간단하고 효율적인 프로그래밍 언어인 Go 언어는 모바일 애플리케이션 개발에서도 강력한 잠재력을 보여주었습니다. 이 기사에서는 Go 언어를 사용하여 모바일 애플리케이션을 개발하는 방법을 자세히 소개하고 독자가 빠르게 시작하고 자신의 모바일 애플리케이션 개발을 시작할 수 있도록 특정 코드 예제를 첨부합니다. 1. 준비 시작하기 전에 개발 환경과 도구를 준비해야 합니다. 머리

Golang 정규 표현식은 파이프 문자 |를 사용하여 여러 단어 또는 문자열을 일치시키고 각 옵션을 논리적 OR 표현식으로 구분합니다. 예: "fox" 또는 "dog"와 일치: fox|dog은 "quick", "brown" 또는 "lazy"와 일치: (quick|brown|lazy)는 "Go", "Python" 또는 "Java"와 일치: Go| Python |Java는 단어 또는 4자리 우편번호와 일치합니다: ([a-zA

"VSCode 이해: 이 도구는 어떤 용도로 사용됩니까?" 》프로그래머로서 초보자이든 숙련된 개발자이든 코드 편집 도구를 사용하지 않으면 할 수 없습니다. 많은 편집 도구 중에서 Visual Studio Code(약칭 VSCode)는 가볍고 강력한 오픈 소스 코드 편집기로 개발자들 사이에서 매우 인기가 높습니다. 그렇다면 VSCode는 정확히 어떤 용도로 사용되나요? 이 기사에서는 VSCode의 기능과 사용법을 자세히 살펴보고 독자에게 도움이 되는 구체적인 코드 예제를 제공합니다.

PHP는 웹 개발의 백엔드에 속합니다. PHP는 주로 서버 측 로직을 처리하고 동적 웹 콘텐츠를 생성하는 데 사용되는 서버 측 스크립팅 언어입니다. 프런트엔드 기술과 비교하여 PHP는 데이터베이스와의 상호 작용, 사용자 요청 처리, 페이지 콘텐츠 생성과 같은 백엔드 작업에 더 많이 사용됩니다. 다음으로, 백엔드 개발에서 PHP 적용을 설명하기 위해 특정 코드 예제가 사용됩니다. 먼저 데이터베이스에 연결하고 데이터를 쿼리하기 위한 간단한 PHP 코드 예제를 살펴보겠습니다.

Go 함수의 가독성과 유지 관리성을 높이려면 다음 모범 사례를 따르세요. 함수 이름을 짧고 설명적이며 동작을 반영하도록 유지하세요. 축약되거나 모호한 이름은 피하세요. 함수 길이는 50~100줄로 제한됩니다. 너무 길면 분할하는 것이 좋습니다. 복잡한 논리와 예외 처리를 설명하기 위해 주석을 사용하여 함수를 문서화합니다. 전역 변수를 사용하지 말고 필요한 경우 명시적으로 이름을 지정하고 범위를 제한하세요.

빠르고 효율적인 프로그래밍 언어인 Go 언어는 백엔드 개발 분야에서 널리 사용됩니다. 그러나 Go 언어를 프런트엔드 개발과 연관시키는 사람은 거의 없습니다. 실제로 프런트엔드 개발에 Go 언어를 사용하면 효율성이 향상될 뿐만 아니라 개발자에게 새로운 지평을 열어줄 수도 있습니다. 이 기사에서는 프런트엔드 개발에 Go 언어를 사용할 수 있는 가능성을 살펴보고 독자가 이 영역을 더 잘 이해할 수 있도록 구체적인 코드 예제를 제공합니다. 전통적인 프런트엔드 개발에서는 사용자 인터페이스를 구축하기 위해 JavaScript, HTML, CSS를 사용하는 경우가 많습니다.
