需要处理的示例文本是:
GLENSTAL EXTRA MATURE COL CHEDDAR 200 GMS,ORIGINAL WAFFLES CO。 英文130G,LIFCO-SHREDDED MOZAREAL-500GM,CAPRICON TASTY面包 -BIG,LUSINE多粒面包片,有机混合果汁JUICE 10X200ML,COLA 330ML(016)PHOENIX有机,水果汁10X 200ML, 有机果汁JUICE 500ML10X
从本文中我必须提取重量,单位和包装是否像“10X或6X”一样可用。我尝试使用正则表达式来解决它,但它并不适用于所有条件。
我尝试过的代码是:
{{1}}
答案 0 :(得分:3)
您可以尝试:
(\d+X\s?)?\d+\s?(LITRE|LTRS|LTR|LIT|GMS|LBS|KG|GM|GR|ML|OZ|LB|G|L)(\d+X\s?)?
如果您只想匹配这些单位。在正则表达式:
(\d+X\s?)?
- 可以将一个或多个数字与X匹配(10X等),\d+\s?
- 一个或多个数字以及一个或没有空白字符(LITRE|LTRS|LTR|LIT|GMS|LBS|KG|GM|GR|ML|OZ|LB|G|L)
- 替代品
你的单位,(\d+X\s?)?
- 可以在单位答案 1 :(得分:2)
尝试使用一个正则表达式来完成所有这些操作可能不值得。也许你可以让它工作,但下一个工作的人将会很难,除非她习惯吹口哨调制解调器。 :-)让我们尝试一系列嵌套循环。
$txt = "GLENSTAL EXTRA MATURE COL CHEDDAR 200 GMS, ORIGINAL WAFFLES CO. ENGLISH 130G, LIFCO-SHREDDED MOZAREAL-500GM, CAPRICON TASTY BREAD -BIG, LUSINE MULTI GRAIN SLICED BREAD, ORGANIC MIXED FRUITS JUICE 10X200ML, COLA 330ML(016) PHOENIX ORGANIC, FRUITS JUICE 10X 200ML, ORGANIC FRUITS JUICE 500ML10X";
$units = array("LITRE", "LTRS", "LTR", "LIT", "GMS", "LBS", "KG", "GM", "GR", "ML", "OZ", "LB", "G", "L");
/* break up your string at the commas, so you handle each item by itself */
$items = preg_split("/\s*,\s*/", $txt);
/* work through the items one by one */
foreach ($items as $item) {
$amtnum = 1;
$amtunit = "";
$packnum = "1";
/* break up the item description into tokens, where
* each number string and letter string gets its own token.
* deal with (123) parenthesized number strings as well.
* e.g. "FRUITS JUICE" "10" "X" "200" "ML"
* and "COLA" "330" "ML" "(016)" "PHOENIX ORGANIC"
*/
$toks = preg_split("/(\(\d+\)|\d+|[^\d\(\)]+)/", $item,-1, PREG_SPLIT_DELIM_CAPTURE|PREG_SPLIT_NO_EMPTY);
/* work backward through array of tokens, using array_pop */
while ($tok = array_pop($toks)) {
/* is the present token in your array of units? */
if (in_array(strtoupper($tok), $units)) {
/* yes. grab next token as the number of units */
$amtunit = $tok;
$amtnum = array_pop($toks);
}
/* is this an X (for a 16X pack or some such thing ? */
if ($tok == 'X') {
/* yes, grab next token as the number of items in the pack */
$packnum = array_pop($toks);
}
/* do what you will with the result */
echo $amtnum, $amtunit, $packnum;
}
}
这一行是解决问题的关键。让我们来研究一下。
$toks = preg_split(
"/(\(\d+\)|\d+|[^\d\(\)]+)/",
$item,-1,
PREG_SPLIT_DELIM_CAPTURE|PREG_SPLIT_NO_EMPTY);
preg_split
将字符串拆分为数组。 PREG_SPLIT_DELIM_CAPTURE
作为修饰符意味着在结果数组中包含正则表达式中的东西。 PREG_SPLIT_NO_EMPTY
表示结果数组中不包含空字符串。
让我们看一下正则表达式本身。我会添加空格以便于阅读。
( \(\d+\) | \d+ | [^\d\(\)]+ )
以括号()
开头和结尾。这与PREG_SPLIT_DELIM_CAPTURE
一致。
然后它包含三个备选匹配表达式,由|
分隔。
第一个是括号,数字和括号。这与测试数据集中的字符串(016)
匹配。
第二个是普通数字。这匹配“300”之类的东西。
第三个是一串字母,空格等,除了数字和括号之外的任何东西。例如,匹配“GMS”和“FRUITS JUICE”。
这可能是使用正则表达式执行此解析作业的一种相当强大的方法。