【问题标题】:php regex to get base64 stringphp正则表达式获取base64字符串
【发布时间】:2020-09-22 15:31:04
【问题描述】:

我有一个包含许多内容的文件 smime.p7m。此内容中的一个或多个是这样的

--_3821f5f5-222-4a90-82e0-d8922ee62cc8_
Content-Type: application/pdf;
name="001235_0001.pdf"
Content-Transfer-Encoding: base64
Content-Disposition: attachment;
filename="001235_0001.pdf"

JVBERi0xLjMNCjMgMCBvYmoNCjw8DQogIC9UeXBlIC9YT2JqZWN0DQogIC9TdWJ0eXBlIC9J
bWFnZQ0KICAvRmlsdGVyIC9EQ1REZWNvZGUNCiAgL1dpZHRoIDI0MDkNCiAgL0hlaWdodCAz
AF6UAFACZoAUUAFABQA1TQAuaADGKAFoASgBaACgBKADpTAQnApAJ0oAdQAdKAD2oAXpQA3p
.........................................
0oAU9KAFHFABQAnSgBOaAFoAKACgAoAWgAoATGOlAAKAFoATpQAYoAO9AC0AFACZ7UAGKAFo
ZPi1JZBodj7GEjdqgELTq0RC7xeSu1yv+dwEltQFPoSMGcbiTf0cGyzbreEAAAAAAAA=
--------------ms021111111111111111111107--

如果文件名是 PDF 和下面的 BASE64 代码,有没有办法使用正则表达式获取文件名?文件中可能存在多个 PDF 文件。

文件名不是问题。我用“filename="(.*).pdf”得到这个。但我不知道如何在文件名之后得到 base64code

【问题讨论】:

  • 在文件名之后你到底想得到什么? ....................? 之前的 3 行?
  • 在寻求正则表达式支持时,通常最好提供多个样本输入来表达输入的可变性。你当然不应该 [yatta-yatta] 你的样本输入。我们需要能够在您的示例输入上运行我们的测试代码。我们需要知道可能会出现多少个空换行符以及文件中的文本序列如何重复。

标签: php regex


【解决方案1】:

base64 由字符 A...Z a...z 数字 0..9 个符号 +/ 组成。最后也可以有一个或两个=,可以拆分成几行。

if (preg_match('/filename=\"(?P<filename>[^"]*?\.pdf)\"\s*(?P<base64>([A-Za-z0-9+\/]+\s*)+=?=?)/', $s, $regres)) {
   print("FileName: {$regres['filename']}\n");
   print("Base64: {$regres['base64']}\n");
}

【讨论】:

  • 谢谢。我明天试试然后回信
【解决方案2】:

使用

(?im)^filename="([^"]*\.pdf)"\R+(.+(?:\R.+)+)

proof

PHP

preg_match_all('/^filename="([^"]*\.pdf)"\R+(.+(?:\R.+)+)/im', $str, $matches);

说明

--------------------------------------------------------------------------------
  (?im)                    set flags for this block (case-
                           insensitive) (with ^ and $ matching start
                           and end of line) (with . not matching \n)
                           (matching whitespace and # normally)
--------------------------------------------------------------------------------
  ^                        the beginning of a "line"
--------------------------------------------------------------------------------
  filename="               'filename="'
--------------------------------------------------------------------------------
  (                        group and capture to \1:
--------------------------------------------------------------------------------
    [^"]*                    any character except: '"' (0 or more
                             times (matching the most amount
                             possible))
--------------------------------------------------------------------------------
    \.                       '.'
--------------------------------------------------------------------------------
    pdf                      'pdf'
--------------------------------------------------------------------------------
  )                        end of \1
--------------------------------------------------------------------------------
  "                        '"'
--------------------------------------------------------------------------------
  \R+                      any line break sequence (1 or more times (matching 
                           the most  amount possible))
--------------------------------------------------------------------------------
  (                        group and capture to \2:
--------------------------------------------------------------------------------
    .+                       any character except \n (1 or more times
                             (matching the most amount possible))
--------------------------------------------------------------------------------
    (?:                      group, but do not capture (1 or more
                             times (matching the most amount
                             possible)):
--------------------------------------------------------------------------------
      \R                       any line break sequence
--------------------------------------------------------------------------------
      .+                       any character except \n (1 or more
                               times (matching the most amount
                               possible))
--------------------------------------------------------------------------------
    )+                       end of grouping
--------------------------------------------------------------------------------
  )                        end of \2

【讨论】:

    【解决方案3】:

    我认为这项任务根本与验证无关,而只关注数据提取——这使得锐化正则表达式逻辑变得不必要。

    您只需要一个在行首匹配filename=" 的模式,然后捕获包含引号的子字符串(只要它以.pdf 结尾),然后在任意数量的空白字符之后,捕获所有字符直到遇到一两个=

    使用贪婪的否定字符类允许正则表达式引擎快速移动。 m 模式修饰符告诉正则表达式引擎 ^ 元字符(不是方括号内使用的 ^)除了字符串的开头之外还可以匹配行的开头。

    也许您想生成一个关联数组,其中键是文件名字符串,编码字符串是值,array_column() 会在存在符合条件的匹配项时快速完成设置。

    代码:(Demo)

    var_export(
        preg_match_all(
            '~^filename="([^"]+)\.pdf"\s*([^=]+={1,2})~m',
            $fileContents,
            $out,
            PREG_SET_ORDER
        )
        ? array_column($out, 2, 1)
        : "no pdf's found"
    );
    

    输出:

    array (
      '001235_0001' => 'JVBERi0xLjMNCjMgMCBvYmoNCjw8DQogIC9UeXBlIC9YT2JqZWN0DQogIC9TdWJ0eXBlIC9J
    bWFnZQ0KICAvRmlsdGVyIC9EQ1REZWNvZGUNCiAgL1dpZHRoIDI0MDkNCiAgL0hlaWdodCAz
    AF6UAFACZoAUUAFABQA1TQAuaADGKAFoASgBaACgBKADpTAQnApAJ0oAdQAdKAD2oAXpQA3p
    .........................................
    0oAU9KAFHFABQAnSgBOaAFoAKACgAoAWgAoATGOlAAKAFoATpQAYoAO9AC0AFACZ7UAGKAFo
    ZPi1JZBodj7GEjdqgELTq0RC7xeSu1yv+dwEltQFPoSMGcbiTf0cGyzbreEAAAAAAAA=',
    )
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-06-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-03-12
      • 2017-05-15
      • 1970-01-01
      相关资源
      最近更新 更多