首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >获取MTOM二进制内容的正则表达式

获取MTOM二进制内容的正则表达式
EN

Stack Overflow用户
提问于 2018-06-13 23:25:19
回答 2查看 809关注 0票数 0

我正在尝试使用SoapClient的扩展类获取MTOM二进制内容,得到的响应是这样的:

    --uuid:8c73f23e-47d9-49fb-a61c-c1df7b19a306+id=2
    Content-ID: 
    <http://tempuri.org/0>
    Content-Transfer-Encoding: 8bit
    Content-Type: application/xop+xml;charset=utf-8;type="text/xml"    

    <big-xml-here>

           <xop:Include href="cid:http://tempuri.org/1/636644204289948690" xmlns:xop="http://www.w3.org/2004/08/xop/include"/>

        </big-xml-here>

--uuid:8c73f23e-47d9-49fb-a61c-c1df7b19a306+id=2--

紧跟在XML之后,MTOM响应继续处理与"cid“URL相关的二进制文件:

Content-ID: <http://tempuri.org/1/636644204289948690>
Content-Transfer-Encoding: binary
Content-Type: application/octet-stream

%PDF-1.4
%���� (lots of binary content here)

--uuid:7329cfb8-46a4-40a8-b15b-39b7b0988b57+id=4--

要提取我尝试过的所有代码,请执行以下操作:

$xop_elements = null;
        preg_match_all('/<xop[\s\S]*?\/>/', $response, $xop_elements);

        $xop_elements = reset($xop_elements);

        if (is_array($xop_elements) && count($xop_elements)) {

            foreach ($xop_elements as $xop_element) {

                $cid = null;
                preg_match('/cid:(.*?)"/', $xop_element, $cid);

                if(isset($cid[1])){
                    $cid = $cid[1];
                    $binary = null;
                    preg_match("/Content-ID:.*?$cid.*?(.*?)uuid/", $response, $binary);
                    var_dump($binary);
                    exit();
                }
            }
        }

虽然preg_match_all和第一个preg_match工作正常,但最后一个:

/Content-ID:.*?$cid.*?(.*?)uuid/ 

是不工作的

在原始源:https://github.com/debuss/MTOMSoapClient/blob/master/MTOMSoapClient.php

正则表达式是

/Content-ID:[\s\S].+?'.$cid.'[\s\S].+?>([\s\S]*?)--uuid/

但是我在PHP 7上得到了一个错误:

preg_match():未知修饰符'/‘

有没有办法获取每个CID的MTOM二进制文件?

提前感谢!

EN

回答 2

Stack Overflow用户

发布于 2018-06-19 04:25:12

您需要先取消对$cid的引用,因为它会导致您的第一个错误

$cid = preg_quote($cid[1], '/');

接下来,您需要使用s修饰符标志,以便.也匹配新行

preg_match("/Content-ID:.*?$cid.*?(.*?)uuid/s", $response, $binary);

s (PCRE_DOTALL)如果设置了此修饰符,则模式中的点元字符将匹配所有字符,包括换行符。如果没有它,换行符将被排除。这个修饰符等同于Perl的/s修饰符。负的类,如^a,总是匹配换行符,与这个修饰符的设置无关。

票数 0
EN

Stack Overflow用户

发布于 2018-06-25 15:34:36

据我所知,您正在尝试将原始代码调整为修改后的文件SOAP版本。

您希望在$cid变量中捕获整个http://tempuri.org/1/636644204289948690,而不是一个数字(您可能希望重命名该变量)。为此,您可以使用以下正则表达式,它匹配捕获组1中除双引号以外的所有内容:cid:([^"]+)

preg_match('/cid:([^"]+)/', $xop_element, $cid);

到现在为止还好。根据您的描述,您应该使用以下模式来捕获二进制部分:

'%Content-ID: <'.$cid.'>([\s\S]*?)--uuid%'

我们使用修改过的点\s\S来匹配多行(如原始实现中所示)。否则,添加s|单行标志或(?s) inline modifier。另外,我使用替代的正则表达式分隔符%来避免转义问题。按照塔伦的建议,使用preg_quote($cid[1], '%')仍然是可行的。

现在,您可以从捕获组1中检索有问题的块:

trim($binary[1]);
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50840958

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档