我有一个字符串,可以很长,包含各种行和字符。
我想要提取被SB& amp;包围的所有行。 EB:
SB1EB
SBa description of various lengthEB
SB123.456.78EB
SB99.99EB
SB99.99EB
SB2EB
SBanother description of various lengthEB
SB123.456.00EB
SB199.99EB
SB199.99EB
3
another description of various length that I don't want to return
123.456.00
599.99
599.99
SB60EB
SBanother description of various length that i want to keepEB
SB500.256.10EB
SB0.99EB
SB0.99EB
another bit of text that i don't want - can span multiple lines
这是我在PHP中使用的模式:
preg_match_all('/SB(\d+)EB\nSB(\w.*)EB\nSB(\d{3}\.\d{3}\.\d{2})EB\nSB(\d.*)EB\nSB(\d.*)EB\n/', $string, $matches)
所以这应该有希望回归:
[0] -> SB1EB
SBa description of various lengthEB
SB123.456.78EB
SB99.99EB
SB99.99EB
[1] -> SB2EB
SBanother description of various lengthEB
SB123.456.00EB
SB199.99EB
SB199.99EB
[2] -> SB60EB
SBanother description of various length that i want to keepEB
SB500.256.10EB
SB0.99EB
SB0.99EB
但我显然做错了,因为它没有匹配任何东西。有人可以帮忙吗?
解决方案:
基于@Sajid回复:
if (preg_match_all('/(?:SB.+?EB(?:[\r\n]+|$))/', $string, $result)) {
for($i=0;$i<count($result[0]);$i++){
$single_item = $result[0][$i];
$single_item = str_replace("SB","",$single_item);
$single_item = str_replace("EB","",$single_item);
if (preg_match('/(\d{3}\.\d{3}\.\d{2})/', $single_item)) {
$id = $single_item;
$qty = $result[0][$i-2];
$name = $result[0][$i-1];
$price = $result[0][$i+1];
$total = $result[0][$i+2];
}
}
}
它有点乱,但它有效! :)
由于
答案 0 :(得分:1)
有点黑客攻击,但这可以胜任:
$a = array();
if (preg_match_all('/(?:SB.+?EB(?:[\r\n]+|$)){5}/', $x, $a)) {
print_r($a);
}
注意?:用于使组不捕获,结果将在$ a [0](例如,$ a [0] [0],$ a [0] [1],$ a [0] [2] ...)
答案 1 :(得分:1)
基于@Sajid reply:
if (preg_match_all('/(?:SB.+?EB(?:[\r\n]+|$))/', $string, $result))
{
for ($i=0; $i<count($result[0]); $i++)
{
$single_item = $result[0][$i];
$single_item = str_replace("SB","",$single_item);
$single_item = str_replace("EB","",$single_item);
if (preg_match('/(\d{3}\.\d{3}\.\d{2})/', $single_item))
{
$id = $single_item;
$qty = $result[0][$i-2];
$name = $result[0][$i-1];
$price = $result[0][$i+1];
$total = $result[0][$i+2];
}
}
}
它有点乱,但它有效! :)
答案 2 :(得分:0)
preg_match_all('/SB\d+EB.*?(?=(?:SB\d+EB)|$)/s', $subject, $result, PREG_PATTERN_ORDER);
for ($i = 0; $i < count($result[0]); $i++) {
# Matched text = $result[0][$i];
}
所以基本上我正在做的事情(根据你的输入)只是检查“标题”字符串SB \ d + EB作为一个入口点并消耗所有内容,直到我找到另一个“标题”或输入的结尾。请注意/ s修饰符。匹配换行符。
<强>解释强>
# SB\d+EB.*?(?=(?:SB\d+EB)|$)
#
# Options: dot matches newline
#
# Match the characters “SB” literally «SB»
# Match a single digit 0..9 «\d+»
# Between one and unlimited times, as many times as possible, giving back as needed (greedy) «+»
# Match the characters “EB” literally «EB»
# Match any single character «.*?»
# Between zero and unlimited times, as few times as possible, expanding as needed (lazy) «*?»
# Assert that the regex below can be matched, starting at this position (positive lookahead) «(?=(?:SB\d+EB)|$)»
# Match either the regular expression below (attempting the next alternative only if this one fails) «(?:SB\d+EB)»
# Match the regular expression below «(?:SB\d+EB)»
# Match the characters “SB” literally «SB»
# Match a single digit 0..9 «\d+»
# Between one and unlimited times, as many times as possible, giving back as needed (greedy) «+»
# Match the characters “EB” literally «EB»
# Or match regular expression number 2 below (the entire group fails if this one fails to match) «$»
# Assert position at the end of the string (or before the line break at the end of the string, if any) «$»