[英]Regular expression for matching between text
我有一个文件,其中包含从apache http日志自动生成的统计数据。
我真的在如何匹配两段文字之间的纠缠。 这是我拥有的统计文件的一部分:
jpg 6476 224523785 0 0
Unknown 31200 248731421 0 0
gif 197 408771 0 0
END_FILETYPES
# OS ID - Hits
BEGIN_OS 12
linuxandroid 1034
winlong 752
winxp 1320
win2008 204250
END_OS
# Browser ID - Hits
BEGIN_BROWSER 79
mnuxandroid 1034
winlong 752
winxp 1320
我正在尝试编写一个正则表达式,该正则表达式仅在标签BEGIN_OS 12
和END_OS
之间搜索。
例如,我想创建一个包含操作系统和热门歌曲的PHP数组(我知道实际的数组实际上并不完全像这样,但是只要我有此数据,就可以了):
array(
[0] => array(
[0] => linuxandroid
[1] => winlong
[2] => winxp
[3] => win2008
)
[1] => array(
[0] => 1034
[1] => 752
[2] => 1320
[3] => 204250
)
)
我已经尝试使用gskinner regex测试器测试正则表达式好几个小时,但是regex远非我的强项。
我会发布到目前为止的内容,但是我尝试了加载,而最接近的是:
^[BEGIN_OS\s12]+([a-zA-Z0-9]+)\s([0-9]+)
可悲的是!
任何帮助将不胜感激,即使它是“无法完成”。
正则表达式可能不是这项工作的最佳工具。 您可以使用正则表达式获取所需的子字符串,然后使用PHP的字符串操作函数进行进一步处理。
$string = preg_replace('/^.*BEGIN_OS \d+\s*(.*?)\s*END_OS.*/s', '$1', $text);
foreach (explode(PHP_EOL, $string) as $line) {
list($key, $value) = explode(' ', $line);
$result[$key] = $value;
}
print_r($result);
应该给您以下输出:
Array
(
[linuxandroid] => 1034
[winlong] => 752
[winxp] => 1320
[win2008] => 204250
)
您可以尝试以下方法:
/BEGIN_OS 12\s(?:([\w\d]+)\s([\d]+\s))*END_OS/gm
您必须仍然为您的结果解析匹配,您还可以使用以下方法简化匹配:
/BEGIN_OS 12([\s\S]*)END_OS/gm
然后,只需解析第一组(它们之间的文本),然后在'\\n'
' '
上分割即可获得所需的部分。
编辑
带有评论的正则表达式:
/BEGIN_OS 12 // Match "BEGIN_OS 12" exactly
\s // Match a whitespace character after
(?: // Begin a non-capturing group
([\w\d]+) // Match any word or digit character, at least 1 or more
\s // Match a whitespace character
([\d]+\s) // Match a digit character, at least one or more
)* // End non-capturing group, repeate group 0 or more times
END_OS // Match "END_OS" exactly
/gm // global search (g) and multiline (m)
和简单的版本:
/BEGIN_OS 12 // Match "BEGIN_OS 12" exactly
( // Begin group
[\s\S]* // Match any whitespace/non-whitespace character (works like the '.' but captures newlines
) // End group
END_OS // Match "END_OS" exactly
/gm // global search (g) and multiline (m)
次要编辑
您的尝试:
^[BEGIN_OS\s12]+([a-zA-Z0-9]+)\s([0-9]+)
不会给您您期望的结果。 如果您将其拆开:
^ // Match the start of a line, without 'm' this means the beginning of the string.
[BEGIN_OS\s12]+ // This means, match a character that is any [B, E, G, I, N, _, O, S, \s, 1, 2]
// where there is at least 1 or more. While this matches "BEGIN_OS 12"
// it also matches any other lines that contains a combination of those
// characters or just a line of whitespace thanks to \s).
([a-zA-Z0-9]+) // This should match the part you expect, but potentially not with the previous rules in place.
\s
([0-9]+) // This is the same as [\d]+ or \d+ but should match what you expect (again, potentially not with the first rule)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.