3

对不起,如果问题措辞不佳(或者如果已经问过。我真的试图找到它)​​。

如果字符类中的一个特定字符恰好是最后一个字符(尽管它仍然可以保留在其他地方),是否有可能将其从匹配中排除?我正在使用的类似于在较大的字符串中查找 url,并且需要在模式中包含句点,但如果最后一个字符是句点,则将其排除在句子的结尾。

所以在一个模式(其他网址的东西)“(/[a-zA-Z0-9._-]*)?” 有没有办法只排除最后一个时期(如果存在)?请注意,上面将具体是域之后的 uri 段,但我只想匹配

"/some_uri/segments.php"

同时

"www.domain.com/some_uri/segments.php" 

"www.domain.com/some_uri/segments.php."

同时允许 uri 中存在多个句点。

如果上述内容不清楚,想象我在寻求一种方法来排除单词中的最后一个字母,当且仅当它是“z”时。所以 'dozzer' 和 'dozzerz' 在句子结构中都匹配为 'dozzer' (所以......不匹配字符串末尾的位置)。我玩过前瞻之类的东西,但还没有找到方法。我想知道这是否不可能(仅在一个正则表达式中)。

谢谢你的时间!

编辑

我很抱歉没有让它更清楚,但我需要在文本块内执行匹配。我正在做的是浏览文本并找到所有网址并对它们应用标记。因此,我不能使用位置运算符,例如 $ 来匹配字符串的结尾。这是最大的问题。

除非其他人发布在此之后有效的答案,否则我认为我将不得不同意 M477h3w1012 并得出结论,它不能单独在正则表达式中完成。在找到匹配项后,我需要执行条件检查以确定它们是否有尾随句点。但再次感谢大家,非常感谢您的时间和帮助。:-)

4

3 回答 3

1

是的。一般来说,这样做:

(<stuff you want to match>)(<character to exclude if at the end>)?$

如果<stuff you want to match>以量词结尾,则该量词必须是非贪婪的,以便排除的最后一个字符存在时将被匹配。

然后使用第一个匹配组($1变量)。

但是,我发现您的正则表达式还有其他一些问题。

  • 如果您希望能够匹配多个字符,则需要在字符类中包含/ 。否则,您只是从第一个/直到下一个之前匹配。
  • 我不知道你为什么有一个在最后。这使得整个事情都是可选的。

此正则表达式将完成您描述的内容:

(/[a-zA-Z0-9._/-]*?)(\.)?$

匹配变量$1将包含从第一个/开始到结尾的所有内容,但如果有最后一个点,则不包括最后一个点(点将在$2中)。

于 2013-07-15T02:25:48.710 回答
1


我认为在单个正则表达式检查中是不可能的......有人可能会纠正我,但我现在不这么认为(或者我现在无法考虑优化事情)。

另一方面,您可以做的是进行检查。首先通过初始替换函数运行输入,看看末尾是否有一个点,如果有则替换它。从那里你可以通过以前的正则表达式来提供它。

所以它可能会这样......

function dotCheck( $url ) {
  $noDotURL = preg_replace( '/\.+$/', '', $url );
  return $noDotURL;
}

urlCheck( dotCheck( $_POST['form'] ) );

其中 urlCheck 是主要检查它是否是有效的链接结构。正则表达式 - 详细形式 - 检查链接中最后一个字符的任何点并删除它们。如果有人输入http://www.google.com ,这应该可以工作。或http://www.google.com .....

快乐的脚本。

于 2013-07-15T01:53:16.607 回答
0

编辑:正如 Adi Inbar 所注意到的,您的目标不是使模式失败,而是排除字符串末尾或单词末尾的特定字符:

排除单词末尾的“z” :(也排除了末尾的几个“z”)

带有字符类和所有格量词:

(?>[^\Wz]++|z++\B)+ # the most performant way

排除“。” 在字符串的末尾:(末尾的几个 '.' 也被排除在外)

展望未来:

^.+?(?=\.*$)

或带有字符类和所有格量词:

(?>[^.]++|\.++(?!$))+

请注意,您可以轻松地将此表达式调整为您需要的更具体的字符类,例如[\w.-]uri:

$pattern = '~(?>/[\w.-]++)*/(?>[\w-]++|\.++(?!$))+/?~';
于 2013-07-15T01:54:21.470 回答