首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >PCRE Regex语法

PCRE Regex语法
EN

Stack Overflow用户
提问于 2012-06-04 20:17:28
回答 3查看 3.8K关注 0票数 2

我想这或多或少是一个由两部分组成的问题,但首先要说明的是:我正在编写一些PHP来使用preg_match_all来查找一个由{}结尾的字符串变量。然后遍历返回的每个字符串,用来自MySQL查询的数据替换它找到的字符串。

第一个问题是:有什么好网站可以真正了解PCRE表达式的来龙去脉?我在谷歌上做了很多搜索,但到目前为止我找到的最好的搜索是http://www.regular-expressions.info/。在我看来,那里的信息没有很好的组织,而且当我需要写一个复杂的正则表达式时,我不想被挂掉,所以请给我指点几个站点(或者几本书!)这样我以后就不用再打扰你们了。

第二个问题是:我有这个正则表达式

代码语言:javascript
复制
"/{.*(_){1}(.*(_){1}[a-z]{1}|.*)}/"

我需要它来捕获诸如{first_name}, {last_name}, {email}等实例。这个正则表达式有三个问题。

首先,它将"{first_name} {last_name}“看作一个字符串,而它应该将它视为两个字符串。我能够通过检查空间的存在来解决这个问题,然后在空间上爆炸。很乱,但很管用。

第二个问题是,它将标点符号作为捕获字符串的一部分。因此,如果您有"{first_name} {last_name} ",那么它将返回逗号作为字符串的一部分。通过简单地使用preg_replace删除句点、逗号和分号,我已经能够部分地解决这个问题。虽然它适用于那些标点符号项,但我的逻辑无法处理感叹号、问号和其他所有内容。

这个正则表达式的第三个问题是它根本没有看到{email}的实例。

现在,如果你可以,愿意,并有时间简单地把这个问题的解决办法交给我,谢谢你,因为这将解决我眼前的问题。不过,即使你能做到这一点,请提供一个很好的网站作为参考和/或一或两本书,将提供良好的教育,这一主题。网站会更好,因为资金紧张,但如果一本书是解决方案,我会找到钱(假设我的当地图书馆系统无法获得上述数量)。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-06-04 20:35:11

那时,我发现PHP自己的PCRE语法引用非常好:http://uk.php.net/manual/en/reference.pcre.pattern.syntax.php

让我们谈谈你的表情。它比必要的要冗长得多;我将在我们讨论这个问题时简化它。

一种比较简单的方法来查看您想要匹配的内容:“查找一个{,然后找到任意数量的字母或下划线,然后是一个}”。它的正则表达式是(在PHP的字符串-y语法中):'/\{[a-z_]+\}/'

这将匹配您的所有示例,但也会匹配一些更疯狂的示例,如{__a_b}。如果这不是一个选项,我们可以使用一个更复杂的描述:“找到一个{,然后是一堆字母,然后(尽可能多地)一个下划线,后面跟着一串字母,然后是一个}”。在正则表达式中:/\{([a-z]+(_[a-z]+)*\}/

第二个可能需要更多的解释。由于我们希望重复与_foo段匹配的内容,所以需要将其放在括号中。然后我们说:尽可能多地找到它,但是如果你根本找不到它也没关系(这就是*的意思)。

现在,我们要比较一下您的尝试,让我们看看是什么导致了您的问题:

  • 表达式匹配{}中的任何字符,包括}{以及其他一系列内容。换句话说,{abcde{_fgh}{abcde} fg_h {ijkl}一样会被正则表达式所接受。
  • 在第一个_之后,这里就有一个强制的.*(_){1} (意思和_完全一样)说:无论发生什么,如果它不在这里,就爆炸吧!很明显,您并不想这样做,因为它永远无法与{email}相匹配。

下面是用普通语言对regex匹配的内容的完整描述:

  1. 匹配一个{
  2. 匹配一个_
  3. 匹配绝对的任何东西,只要你能匹配所有剩余的规则,在那之后,任何事情。
  4. 匹配一个_
  5. 匹配一个字母。
  6. _和一个字母相比,任何事情都是可以的。
  7. 匹配一个}

这可能和你想要的相去甚远。不过别担心。正则表达式需要一段时间才能适应。我认为,如果你从指令的角度来考虑它,比如,当你构建一个正则表达式的时候,试着把它构建成一个“找到这个,然后找到那个”等等,然后找出正确的语法来实现这一点。

这很难,主要是因为并不是所有你脑子里想出来的指令都能很容易地转化成一个正则表达式.但这就是经验的来源。我向你保证你很快就会把它放下的.如果您在一开始做正则表达式时相当有条不紊。

祝你好运!)

票数 3
EN

Stack Overflow用户

发布于 2013-02-05 02:27:19

对于PCRE,我只是简单地消化了PCRE手册,但是我的大脑无论如何都是这样工作的.

至于匹配分隔的内容,通常有两种方法:

  1. 匹配第一个分隔符,匹配任何不是结束分隔符的内容,匹配结束分隔符。
  2. 匹配第一个分隔符,不贪婪地匹配任何内容,匹配结束分隔符。

就你的情况而言:

  1. \{([^}]+)\}
  2. \{(.+?)\} -注意在+之后

我在您可能想要提取的内容周围添加了一个组。

还请注意,特别是在#1的情况下,而且对于#2,如果“点匹配任何东西”是有效的(dotall,singleline或您最喜欢的regex风味调用它),它们也将匹配内部的换行符--如果这将是一个问题,则需要手动排除它和其他您不想要的内容;如果您想要更像白名单方法的东西,请参阅上面的答案。

票数 1
EN

Stack Overflow用户

发布于 2014-11-21 03:00:12

  1. 这是一个好的regex站点
  2. 下面是一个可以工作的PCRE正则表达式:\{\w+\}

下面是它的工作原理:它基本上是在寻找{,然后是one ore more word characters,然后是}。有趣的是,单词字符类实际上也包含一个下划线。\w本质上是[A-Za-z0-9_]的缩写

因此,它将基本上匹配大括号内所有这些字符的组合,因为加号只匹配不为空的大括号。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10887744

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档