提取符合特定条件的“单词”

问题描述

| 我有以下字符串:   SEDCVBNT S800BG09 7GFHFGD6H 324235346 RHGF7U S8-00BG / 09 7687678 和以下正则表达式:
preg_match_all(\'/\\b(?=.+[0-9])(?=.+[A-Z])[A-Z0-9-\\/]{4,20}/i\',$string,$matches)
我要达到的目标是返回所有的“单词”: 至少包含1个数字 至少包含1个字母 可能含有 \'/\' 可能含有 \'-\' 不幸的是,上面的正则表达式返回:
Array ( [0] => Array ( [0] => SEDCVBNT [1] => S800BG09 [2] => 7GFHFGD6H [3] => 324235346 [4] => RHGF7U [5] => S8-00BG/09 ) ) 
我不希望返回“ SEDCVBNT”或“ 324235346”。 我已经搜索了很多内容,尝试对上述正则表达式进行了许多小的更改,但是我完全陷入了困境。我非常感谢您的帮助。 提前致谢。     

解决方法

        这是原始的正则表达式:
\\b(?=\\S*?\\d)(?=\\S*?[a-z])\\S+?(?=$|\\s)
preg_match_all(\'/\\b(?=\\S*?\\d)(?=\\S*?[a-z])\\S+?(?=$|\\s)/i\',$string,$matches) 
    ,        您需要为此使用稍微高级的regex语法。 我想出的正则表达式是
(?<=\\s|^)(?=[\\w/-]*\\d[\\w/-]*)(?=[\\w/-]*[A-Za-z][\\w/-]*)([\\w/-])+(?=\\s|$)
让我们来解释一下: 语法
[\\w/-]
出现了很多;这意味着\“任何单词字符(包括字母,数字,带重音的字母等)或斜杠或破折号\”-实际上,您认为属于有效令牌的所有字符。 正则表达式使用积极的前瞻性来确保在尝试匹配的地方,以下文本确实满足某些条件。正向超前看起来像这样:
(?=[\\w/-]*\\d[\\w/-]*)
。 它还使用正号(末尾的数字:
(?=\\s|$)
)和负号(开始的数字:
(?<=\\s|^)
)进行前瞻,以确保仅当整个文本标记在空格字符之后开始或在输入的开头时才进行匹配字符串(
\\s|^
),后跟一个空格字符或终止输入字符串(
\\s|$
)。 由于两个内部超前模式几乎与捕获组模式
([\\w/-])+
相同,实际上,我使用它们来匹配匹配多个模式的文本:前瞻和末尾的捕获组模式。 首先进行前瞻确保下一个令牌至少包含一位数字(
\\d
)。 第二次前瞻确保下一个令牌至少包含一个字母(
A-Za-z
)。 捕获组匹配一个或多个单词字符和/或
/
-
。 因此,为了使捕获组匹配,要检查的文本必须: 在空格之前或输入字符串的开头(这可以防止部分单词匹配在不允许的字符之后开始) 在下一个允许的字符段中至少包含一位数字(第一个正向超前) 在下一个允许的字符段中至少包含一个字母(第二个正向超前) 仅由单词字符
/
-
(捕获组)组成。 后面要跟空格或输入字符串的结尾(这可以防止部分单词匹配以不允许的字符结尾)。 正是您所需要的。 :) 看到它的行动! 注意:refiddle.com似乎在负向后看时不能很好地发挥作用,因此链接后的正则表达式不包含开头的
(?<=\\s|^)
部分。这意味着它将错误地匹配
ABC123$DEF456
中的
DEF456
。