【问题标题】:complicated string manipulation in PHPPHP中复杂的字符串操作
【发布时间】:2015-05-14 05:28:39
【问题描述】:

我有一个类似这样的表格。

 <form id="formPropiedades" name="formPropiedades" method="post" action="./index.php">
        <table width="70%" cellpadding="2" border="1" style="margin: 0 auto;margin-bottom:70px" class="parametros">
            <caption>
                <h1>Parámetros generales de la plantilla</h1>
            </caption>
            <tbody>
                <tr>
                    <th colspan="2">Campo</th>
                    <th colspan="6">Filtro</th>
                </tr>
                <tr class="row">
                    <td class="dbList" colspan="2">Address</td>
                    <td colspan="6">
                        <input type="text" style="width: 100%;border: solid 1px black;" name="inp[]" value="">
                        <select id="tablaCampo1" class="tablaCampo1" name="tablaCampo1">
<option value="SALTEST.ANUNCIO.ID_CIUDAD">SALTEST.ANUNCIO.ID_CIUDAD</option>
                            <option value="SALTEST.ANUNCIO.CIUDAD">SALTEST.ANUNCIO.CIUDAD</option>
                            <option value="SALTEST.ANUNCIO.MUNICIPIO">SALTEST.ANUNCIO.MUNICIPIO</option>
                            <option value="SALTEST.ANUNCIO.ID_ESTADO">SALTEST.ANUNCIO.ID_ESTADO</option>
                            <option value="SALTEST.ANUNCIO.ESTADO">SALTEST.ANUNCIO.ESTADO</option>
                            <option value="SALTEST.ANUNCIO.ID_MUNICIPIO">SALTEST.ANUNCIO.ID_MUNICIPIO</option>

                        </select>
                        <button class="makeStrng" type="button">+</button>
                    </td>
                </tr>
                <tr>
                    <td align="right" colspan="8">
                        <input type="button" id="guardarBtn" value="guardar" name="guardar" style=" float:left">
                        <input type="button" id="step1" value="prev" name="prev">
                        <input type="submit" id="propiedades" value="Enviar" name="submitme">
                    </td>
                </tr>
            </tbody>
        </table>
    </form>

所以 select 中的选项实际上是 XML 中的列。这具有相应字段的数据

给你一个想法,xml看起来像这样

<SALTEST>

<ANUNCIO>
    <CIUDAD>Some Name</CIUDAD>
    <MUNICIPIO>SOme Name </MUNICIPIO>
    <ESTADO>Some name </ESTADO>
</ANUNCIO>
<ANUNCIO>
    <CIUDAD>Some Name</CIUDAD>
    <MUNICIPIO>SOme Name </MUNICIPIO>
    <ESTADO>Some name </ESTADO>
</ANUNCIO>

<SALTEST>

用户将使用选择选项并创建一个字符串,该字符串将具有创建内容的设置

例如

要创建地址字符串,用户将保存这样的设置。

字符串1:

<fld>SALTEST.ANUNCIO.ESTADO </fld><fld>SALTEST.ANUNCIO.MUNICIPIO </fld><fld>SALTEST.ANUNCIO.CIUDAD</fld>

STRING2

 <fld>SALTEST.ANUNCIO.ESTADO</fld><ltr>,</ltr> <fld>SALTEST.ANUNCIO.MUNICIPIO</fld><ltr>,</ltr><fld>SALTEST.ANUNCIO.CIUDAD</fld>

STRING3:

<fn>if(<fld>SALTEST.ANUNCIO.ID_CIUDAD</fld>,<fld>SALTEST.ANUNCIO.ID_CIUDAD</fld>,"<",<fld>SALTEST.ANUNCIO.ID_CIUDAD</fld>)</fn>

所以基本上字符串会有三种类型的分隔符。

1.&lt;fld&gt;&lt;/fld&gt; 这些是要从 XML 中使用的字段。

2.&lt;fn&gt;&lt;/fn&gt; 这些之间的任何东西都是一个函数,我告诉系统将它检测为一个函数

3.&lt;ltr&gt;&lt;/ltr&gt; 这些之间的任何东西都是必须用来分隔每个的字符

例如:

 <fld>SALTEST.ANUNCIO.ESTADO</fld><ltr>,</ltr> <fld>SALTEST.ANUNCIO.MUNICIPIO</fld><ltr>,</ltr><fld>SALTEST.ANUNCIO.CIUDAD</fld>

应该给 某个名字,某个名字,某个名字。

我必须编写一个 PHP 脚本来检测每种类型的字符串,然后应用相关功能

【问题讨论】:

  • 不要进行字符串操作。使用 XML DOM 解析器解析 STRING2STRING3
  • @Barmar 但这些只是普通字符串,&lt;fld&gt; 等标签只是假设性的。我刚才创建是为了更好地解释我的概念。但我将研究如何使用 XM DOM 解析器
  • 由于它们的格式类似于 XML/HTML 标签,您可以使用 DOM 解析器来解析它们。
  • 虽然 OP 的字符串与 XML 非常相似,但我看到标签之间的字符我假设他打算保留 - 我不确定这是否可以使用 DOM 解析器来完成......
  • @PeterBowers 当然可以,它们将在文本节点中。

标签: php xml string


【解决方案1】:

您想创建一个正则表达式来识别周围的标签并提取其间的内容。然后,调用一个函数来决定应该用什么特定的标签组合替换。 preg_replace_callback 似乎是你的功能du jour

$newstr = '';
while ($newstr != $subject) {
        if ($newstr)
            $subject = $newstr;
        echo "subject=".str_replace('<', '&lt;', $subject)."<br />\n";
        $newstr = preg_replace_callback('/<(fld|fn|ltr)>([^>]*?)<\/\\1>/', 
            function ($matches) {
                // $matches[1] contains 'fld' or 'fn' or 'ltr'
                // $matches[2] contains the string between the tags
                echo "matches=<pre>".print_r($matches,true)."</pre><br />\n";
                switch ($matches[1]) {
                case 'fld':
                    // here you look up the string in $matches[2] from your XML and return it
                    return "fld:$matches[2]";
                    break;
                case 'fn':
                    // here you call whatever function with arg of $matches[2] and return result
                    return "fn:$matches[2]";
                    break;
                case 'ltr':
                    return "ltr:$matches[2]";
                    return $matches[2];
                    break;
                }
            }, $subject);
        echo "anewstr=".str_replace('<', '&lt;', $newstr)."<br />\n";
        if ($newstr == $subject) {
            echo "Breaking...<br />\n";
            break;
        }
}

从技术上讲,由于您在每种情况下都返回一个值,因此您不需要 break;,但我认为将其保留在那里是一种很好的形式。

【讨论】:

  • &lt;fn&gt; 将成为您的挑战,因为它显然允许嵌套标签。您可能希望将我的 (.*?) 更改为 ([^&lt;]*) 以确保您首先处理所有内部标签 - 但是,如果您在 &lt;fn&gt;...&lt;/fn&gt; 中有除 fn/fld/ltr 之外的任何标签,那么它将失败。
  • 哈哈,@ThW!但我不是 100% 确定 - 你是说我们应该或不应该用正则表达式解析 HTML...? :-)
  • @PeterBowers 你能告诉我如何将字符串传递给你在答案中提到的函数。
  • @PeterBowers 当我尝试解析第一个字符串时,它显示以下错误。 preg_replace_callback() [&lt;a href='function.preg-replace-callback'&gt;function.preg-replace-callback&lt;/a&gt;]: Unknown modifier '\' on line 18
  • 好的,我这次真的试过了,现在可以了。但是,它仍然不能处理嵌套标签。为此,只要返回的值正在更改字符串,您就必须多次调用它 - 我 认为 可以解决它。但是,基于上述其他 cmets,我认为我不会继续开发基于正则表达式的解决方案......
猜你喜欢
  • 1970-01-01
  • 2016-11-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-20
  • 2012-07-16
  • 2022-01-20
  • 2016-12-16
相关资源
最近更新 更多