我有一个包含 5 个单词的字符串。在字符串中,其中一个单词是业余无线电呼号,可以是美国数千个呼号中的任何一个。为了从字符串中提取呼号,我需要使用以下模式。我需要提取的呼号可以位于字符串中的 5 个位置中的任何一个。数字从来不是第一个字符,数字也永远不会是最后一个字符。字符串实际上是从数组中组合在一起的,因为它最初是从文本文件中读取的。
$string = $word[1] $word[2] $word[3] etc....
因此,搜索可以对整个字符串或数组的每个部分进行。
Patterns:
1 Number and 3 Letters Example: AB4C A4BC
1 Number and 4 Letters Example: A4BCD
1 Number and 5 Letters Example: AB4CDE
我已经尝试了我能想到的一切并搜索,直到我无法再搜索。我敢肯定,我想得太多了。
像这样的两步正则表达式就可以了:
$str = "hello A4AB there BC5AD";
$signs = array();
preg_match_all('/[A-Z][A-Z'd]{1,3}[A-Z]/', $str, $possible_signs);
foreach($possible_signs[0] as $possible_sign)
if (preg_match('/^'D+'d'D+$/', $possible_sign))
array_push($signs, $possible_sign);
print_r($signs); //Array ([0] => A4AB [1] => BC5AD)
解释
这是一种正则表达式方法,使用两种模式。我认为它不能用一个来完成,并且仍然满足匹配规则的确切要求。
第一种模式强制实施以下要求:
- 子字符串以大写字母开头和结尾
- 子字符串仅包含第一个和最后一个字母之间的其他大写字母或数字
- 子字符串总体长度不超过 6 个字符
出于复杂的 REGEX 原因,我无法在相同的模式中做(除非有人知道一种方法并且可以纠正我),是强制只包含一个数字。
@jeroen的答案确实在单个模式中强制执行这一点,但反过来又不会强制执行子字符串的正确长度。无论哪种方式,我们都需要第二种模式。
因此,在抓住最初的比赛后,我们循环查看结果。然后,我们将每个模式应用于第二个模式,该模式仅强制子字符串中只有一个数字。
如果是这样,我们将子字符串开绿灯,然后将其添加到$signs
数组中。
希望这有帮助。
这取决于其他单词可以包含的内容,但您可以使用正则表达式,例如:
#'b[a-z]+'d[a-z]+'b#i
^ case insensitive
^^ a word boundary
^^^^^^ One or more letters
^^ One number
您可以通过对字母使用 {1,3}
而不是 +
来使其更具限制性,以便您有一个由 1 到 3 个字母组成的序列。
完整的表达式如下所示:
$success = preg_match('#'b[a-z]+'d[a-z]+'b#i', $input_string, $matches);
如果$matches[0]
将包含匹配的值,请参阅手册。