19

我需要找到所有一位数字的文本。

我的代码:

$string = 'text 4 78 text 558 my.name@gmail.com 5 text 78998 text';
$pattern = '/ [\d]{1} /';

(结果:4 和 5)

一切正常,只是想问使用空格是否正确?也许还有其他方法可以区分一位数。

谢谢

4

5 回答 5

26

首先,[\d]{1}等价于\d

至于您的问题,最好使用零宽度断言,例如后向/前瞻或单词边界(\b)。否则,您将不会匹配连续的单个数字,因为第二个数字的前导空格将与第一个数字的尾随空格匹配(并且不会找到重叠匹配)。

这是我将如何写这个:

(?<!\S)\d(?!\S)

这意味着“仅当数字之前没有非空白字符且其后没有非空白字符时才匹配数字”。

我使用了双重否定,(?!\S)而不是(?=\s)这样你也将匹配字符串开头或结尾的单个数字。

对于你的例子,我更喜欢这个,\b\d\b因为看起来你真的只想在数字被空格包围时匹配,并且\b\d\b会匹配字符串中的45192.168.4.5

要在末尾允许标点符号,您可以使用以下内容:

(?<!\S)\d(?![^\s.,?!])

在字符类的数字之后添加您希望允许的任何其他标点字符(在方括号内,但确保它在 之后^)。

于 2013-02-26T21:03:55.737 回答
18

使用单词边界。请注意,范围量词{1}(单个\d将只匹配一个数字)和字符类[]是多余的,因为它只包含一个字符。

\b\d\b
于 2013-02-26T21:01:58.080 回答
6

搜索单词边界:

\b\d\b

正如其他人所解释的那样,这将提取单个数字,这意味着某些特殊字符可能不被尊重,例如“。” 在一个 IP 地址中。要解决这个问题,请参阅 FJ 和 Mike Brant 的回答。

于 2013-02-26T21:01:33.543 回答
0

这实际上取决于数字可以出现在哪里以及您是否关心它们是否与其他字符相邻(例如.在句子的末尾)。至少,我会使用单词边界,以便您可以在输入字符串的开头和结尾获取数字:

$pattern = '/\b\d\b/';

但您可能会在结尾考虑标点符号,例如:

$pattern = '/\b\d(\b|\.|\?|\!)/';
于 2013-02-26T21:05:32.130 回答
0

如果一位数字前面或后面可以跟数字以外的字符(例如,"a1 cat""Call agent 7, pronto!"),请使用

(?<!\d)\d(?!\d)

演示

正则表达式读取,匹配一个\d既不是在数字之前也不是在数字之后的数字 (),是(?<!\d)一个否定的lookbehind(?!\d)一个否定的lookahead

于 2021-10-07T22:31:18.350 回答