首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >提取可能是数字或字母数字的SKU值,并且必须有4到20个字符长。

提取可能是数字或字母数字的SKU值,并且必须有4到20个字符长。
EN

Stack Overflow用户
提问于 2022-01-11 19:52:17
回答 2查看 184关注 0票数 1

我愿意包含更多的代码,而不仅仅是正则表达式。

我正在编写一些代码,拍摄一张照片,运行两个Imagick过滤器,然后运行一个tesseractOCR传递,以输出文本。

从该文本中,我使用带PHP的regex提取一个SKU (产品的模数)并将结果输出到一个数组中,然后将数组插入到一个表中。

一切都很好,除了我现在用的表情:

@#-$^&*():;,œ∑††π∂ƒc.∆˚Ω≈√∫˜≤≥{4,20}

我还会得到一些只包含字母的字符串。

最终目标是:

可以包含大写字母和数字的-strings,

只包含数字的-strings,

不包含字母的-strings,

不包含任何小写字母的-strings,

-these字符串必须介于4-20个字符之间。

例如:

SKU可以是5209,也可以是WRE5472UFG5621

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2022-01-11 22:23:43

在regex ma雌激素出现之前,像我这样的懒人只会在这个问题上做两轮,并且保持简单。首先,匹配所有仅为A-Z0-9的字符串(而不是编制大量的无列表或外观)。然后,使用带有preg_grep()标志的PREG_GREP_INVERT删除所有仅为A的字符串。最后,过滤唯一的匹配,以消除重复噪声。

代码语言:javascript
运行
复制
$str = '-9 Cycles 3 Temperature Levels Steam Sanitizet+ -Sensor Dry | ALSO AVAILABLE (PRICES MAY VARY) |- White - 1258843 - DVE45R6100W {+ Platinum - 1501 525 - DVE45R6100P desirable: 1258843 DVE45R6100W';

$wanted = [];

// First round: Get all A-Z, 0-9 substrings (if any)
if(preg_match_all('~\b[A-Z0-9]{6,24}\b~', $str, $matches)) {

    // Second round: Filter all that are A-Z only
    $wanted = preg_grep('~^[A-Z]+$~', $matches[0], PREG_GREP_INVERT);

    // And remove duplicates:
    $wanted = array_unique($wanted);
}

结果:

代码语言:javascript
运行
复制
array(3) {
    [2] · string(7) "1258843"
    [3] · string(11) "DVE45R6100W"
    [4] · string(11) "DVE45R6100P"
}

请注意,我已经将匹配长度增加到了{6,24},尽管您提到了一个4个字符的匹配,因为示例字符串中有不属于“理想”列表的4位子字符串。

编辑:--我已经将preg_match_all()移动到包含其余操作的条件构造中,默认情况下将$wanted设置为空数组。您可以方便地捕获匹配,并评估是否一次匹配(而不是有if(!empty($matches)))。

更新:在@mickmackusa的回答中使用了一个更有说服力的regex,使用了查找,我对过滤的“普通”正则表达式的性能感到好奇,而不是使用查找。然后,一个测试用例 (仅在3v4l处进行1次迭代以避免轰炸它们,请使用您自己的服务器获取更多!)。

测试用例使用了100个具有潜在匹配的生成字符串,使用这两种方法在5000次迭代中运行。返回的匹配结果是相同的。具有前瞻性的单步正则表达式平均花费0.83秒,而两步“平原”正则表达式平均花费0.69秒。看起来,使用前瞻性比“直截了当”的方法要贵得多。

票数 0
EN

Stack Overflow用户

发布于 2022-01-12 21:40:00

好吧,你已经接受了一个间接的答案,因为我在问题下面的评论中要求改进问题。我的理解是,这意味着你不打算进一步澄清这个问题,而另一个答案则按你的意愿工作。因此,我将提供一个regex解决方案,这样您就不需要在进行初始regex提取之后使用迭代regex筛选。

对于有限的样本数据,您的需求归结为:

匹配整个“单词”(由空格分隔的可见字符),其中:

  1. 由数字或字母数字字符串和
  2. 长度在4到20个字符之间。

如果需要,可以随后使用array_unique()消除重复的匹配字符串。

代码:(演示)

代码语言:javascript
运行
复制
$str = '-9 Cycles 3 Temperature Levels Steam Sanitizet+ -Sensor Dry | ALSO AVAILABLE (PRICES MAY VARY) |- White - 1258843 - DVE45R6100W {+ Platinum - 1501 525 - DVE45R6100P desirable: 1258843 DVE45R6100W';

if (preg_match_all('~\b(?:[A-Z]{4,20}(*SKIP)(*FAIL)|[A-Z\d]{4,20})\b~', $str, $m)) {
    var_export(array_unique($m[0]));
}

输出:

代码语言:javascript
运行
复制
array (
  0 => '1258843',
  1 => 'DVE45R6100W',
  2 => '1501',
  3 => 'DVE45R6100P',
)

模式分解:

代码语言:javascript
运行
复制
\b             #the zero-width position between a character matched by \W and a character matched by \w
(?:            #start non-capturing group
  [A-Z]{4,20}(*SKIP)(*FAIL) #match and disqualify all-letter words
  |                         #or
  [A-Z\d]{4,20}             #match between 4 and 20 digits or uppercase letters
)              #end non-capturing group
\b             #the zero-width position between a character matched by \W and a character matched by \w

这里有几种可供比较的可选择的正则表达式--一种不使用任何旁观者的模式,使用“跳过失败”技术来取消纯粹按字母顺序排列的“单词”。

  • 437步:\b(?=\S*\d)[A-Z\d]{4,20}\b
  • 325个步骤:\b(?=[A-Z]*\d)[A-Z\d]{4,20}\b
  • 298个步骤:\b(?:[A-Z]{4,20}(*SKIP)(*FAIL)|[A-Z\d]{4,20})\b

等价的非正则化过程(我不赞同)是:(演示)

代码语言:javascript
运行
复制
foreach (explode(' ', $str) as $word) {
    $length = strlen($word);
    if ($length >= 4                    // has 4 characters or more
        && $length <= 20                // has 20 characters or less
        && !isset($result[$word])       // not yet in result array
        && ctype_alnum($word)           // comprised numbers and/or letters only
        && !ctype_alpha($word)          // is not comprised solely of letters
        && $word === strtoupper($word)  // has no lowercase letters
    ) {
        $result[$word] = $word;
    }
}
var_export(array_values($result));
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70672645

复制
相关文章

相似问题

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