在PHP中解析CSV文件和匹配模式

时间:2013-07-03 07:37:12

标签: php regex pattern-matching fgetcsv

我有一个CSV文件,如下所示

***Client Name: abc***,
,
# ----------------------------------------,
# Twitter : Mentions - Count,
# ----------------------------------------,
Date/Time (GMT),abc
6/6/2013,1
6/11/2013,3
6/12/2013,2
6/13/2013,1
6/14/2013,2
6/15/2013,4
6/17/2013,4
6/18/2013,8
6/19/2013,7
# *** Interval: Daily ***,
,
***Client Name: abc***,
,
# ----------------------------------------,
# Facebook Insights : Likes by Source,
# ----------------------------------------,
Sources,Likes
Mobile,3602
Page Profile,470
Recommended Pages,86
Ads,64
Like Story,49
Mobile Sponsored Page You May Like,44
Page Browser,33
Search,22
Timeline,16
Mobile Page Suggestions On Liking,15
3 more sources,48
,
***Client Name: xyz***,
,
# ----------------------------------------,
# Twitter : Mentions - Count,
# ----------------------------------------,
Date/Time (GMT),xyz
6/12/2013,1
# *** Interval: Daily ***,
,
***Client Name: pqr***,
,
# ----------------------------------------,
# Twitter : Mentions - Count,
# ----------------------------------------,
Date/Time (GMT),pqr
6/6/2013,2
6/7/2013,3
6/9/2013,6
6/10/2013,1
6/12/2013,4
6/13/2013,1
6/14/2013,9
6/15/2013,5
6/16/2013,1
6/18/2013,2
6/19/2013,2
# *** Interval: Daily ***,

我要提取Twitter:提及 - 计算数据并保存数据库中的所有内容。

我想要

之间的内容
# ----------------------------------------,
# Twitter : Mentions - Count,
# ----------------------------------------,

 # *** Interval: Daily ***,

如何在PHP中匹配此模式是否有任何与类文件匹配的php类或如何使用regax执行此操作。

我对模式匹配一​​无所知我刚刚尝试使用fgetcsv()读取csv文件

 $file = fopen($uploaded_file_path, 'r');
            echo "<pre>";
            while (($line = fgetcsv($file)) !== FALSE) {
              print_r($line);
            }
            fclose($file);

2 个答案:

答案 0 :(得分:1)

描述

此正则表达式将找到每个节标题Twitter Mentions - Count并将节主体捕获到组1中。

^\#\sTwitter\s:\sMentions\s-\sCount,[\s\r\n]+    # match the header
^\#\s----------------------------------------,[\s\r\n]+   # match the separator line
(^(?:(?!\#\s\*\*\*\sInterval:\sDaily\s\*\*\*,).)*)    # match the rest of the string upto the first Interval Daily

enter image description here

扩展

  • 第一部分简单地找到每个块的开头,它是很多字符,但很大程度上是直接的。

    • ^匹配行的开头,需要多行选项,通常为m
    • \#\sTwitter\s:\sMentions\s-\sCount,匹配此完全字符串,请注意\s将匹配空格字符,我这样做是因为我喜欢使用忽略空格选项,通常是x
    • [\s\r\n]+匹配一个或多个空格或换行符。
    • ^\#\s----------------------------------------,[\s\r\n]+这匹配从行^的开头到结尾的新行字符的分隔行中的字符
  • 此部分捕捉该部分的正文,并且是真正的魔法发生的地方。

    • (启动捕获组1
    • ^确保我们匹配行的开头,这可确保下一个前瞻正确验证
    • (?:启动非捕获组。这种非捕获组的构造在遇到负前瞻内部的不合需要的字符串时会自行终止。这将最终捕获上面的节标题和结束字符串之间的每个字符。
    • (?!开始否定前瞻,这将验证我们不会进入标记该部分结束的不良关闭文本。
    • \#\s\*\*\*\sInterval:\sDaily\s\*\*\*,匹配不受欢迎的文字。如果找到,则否定前瞻将失败
    • )关闭负面展望
    • .匹配任何字符,预计“点匹配新行”选项通常为s
    • )关闭非捕获组
    • *允许非捕获组重复零次或多次。
    • )关闭捕获组1.由于此捕获组内发生的所有匹配.都将存储在此处。

PHP示例

直播示例:http://www.rubular.com/r/stgaiBeSE1

示例文字

***Client Name: abc***,
,
# ----------------------------------------,
# Twitter : Mentions - Count,
# ----------------------------------------,
Date/Time (GMT),abc
6/6/2013,1
6/11/2013,3
6/12/2013,2
6/13/2013,1
6/14/2013,2
6/15/2013,4
6/17/2013,4
6/18/2013,8
6/19/2013,7
# *** Interval: Daily ***,
,
***Client Name: abc***,
,
# ----------------------------------------,
# Facebook Insights : Likes by Source,
# ----------------------------------------,
Sources,Likes
Mobile,3602
Page Profile,470
Recommended Pages,86
Ads,64
Like Story,49
Mobile Sponsored Page You May Like,44
Page Browser,33
Search,22
Timeline,16
Mobile Page Suggestions On Liking,15
3 more sources,48
,
***Client Name: xyz***,
,
# ----------------------------------------,
# Twitter : Mentions - Count,
# ----------------------------------------,
Date/Time (GMT),xyz
6/12/2013,1
# *** Interval: Daily ***,
,
***Client Name: pqr***,
,
# ----------------------------------------,
# Twitter : Mentions - Count,
# ----------------------------------------,
Date/Time (GMT),pqr
6/6/2013,2
6/7/2013,3
6/9/2013,6
6/10/2013,1
6/12/2013,4
6/13/2013,1
6/14/2013,9
6/15/2013,5
6/16/2013,1
6/18/2013,2
6/19/2013,2
# *** Interval: Daily ***,

<强>代码

<?php
$sourcestring="your source string";
preg_match_all('/^\#\sTwitter\s:\sMentions\s-\sCount,[\s\r\n]+
^\#\s----------------------------------------,[\s\r\n]+
(^(?:(?!\#\s\*\*\*\sInterval:\sDaily\s\*\*\*,).)*)/imsx',$sourcestring,$matches);
echo "<pre>".print_r($matches,true);
?>

来自Capture Group 1的匹配

[0] => Date/Time (GMT),abc
    6/6/2013,1
    6/11/2013,3
    6/12/2013,2
    6/13/2013,1
    6/14/2013,2
    6/15/2013,4
    6/17/2013,4
    6/18/2013,8
    6/19/2013,7

[1] => Date/Time (GMT),xyz
    6/12/2013,1

[2] => Date/Time (GMT),pqr
    6/6/2013,2
    6/7/2013,3
    6/9/2013,6
    6/10/2013,1
    6/12/2013,4
    6/13/2013,1
    6/14/2013,9
    6/15/2013,5
    6/16/2013,1
    6/18/2013,2
    6/19/2013,2

            )

答案 1 :(得分:0)

试试这个

public static function csv_to_array($filename='', $delimiter=',')
 { 
    if(!file_exists($filename) || !is_readable($filename))
        return FALSE;

    $header = NULL;
    $data = array();
    if (($handle = fopen($filename, 'r')) !== FALSE)
    {
        while (($row = fgetcsv($handle, 1000, $delimiter)) !== FALSE)
        {
                $data[] = $row;
        }
        fclose($handle);
    }
    return $data;
 }