PHP preg_match_all 表达式

发布于 2024-10-11 13:23:23 字数 1096 浏览 3 评论 0原文

我几乎没有 regx 的经验,但我尽力了。

我有一个像这样的字符串:

$fString = "Name=Sök,Value=2,Title=Combine me,Options=[Item1=1,Item2=2,Item3=3]";

我想要一个看起来像这样的数组:

Array[0] = "Name=Sök"
Array[1] = "Value=2"
Array[2] = "Title=Combine me"
Array[3] = "Options=[Item1=1,Item2=2,Item3=3]"

到目前为止我所做的是:

preg_match_all("/[^,]*[\w\d]*=[^,]*/",$fString,$Data);

但我不知道如何修复最后一个“选项”。

Array ( [0] => Array ( [0] => Name=S�k [1] => Value=2 [2] => Title=Combine me [3] => Options=[Item1=1 [4] => Item2=2 [5] => Item3=3] ) )

...为什么结果是数组中的数组?!?


[编辑]

我想我需要解释一下我在这里尝试做的事情的整个想法,我不确定我是否走在正确的轨道上。

我创建了一些类,将所有“持久”变量存储在数组中。我有一个函数可以序列化这个数组,这样我就可以将其存储在数据库中。

我知道有关serialize()函数的所有信息,但我正在做一些过滤,所以我不能按原样使用它,而且我也更喜欢让它更易于手动编辑可读。该数组可以包含需要保留的嵌套数组。当我从数据库中读回所有内容时,必须再次创建原始数组。

我已经使用 eval() 命令完成了所有工作,但由于“或 ' 字符破坏了主外部字符串,所以我在嵌套数组时遇到了麻烦。因此,这种方法是尝试序列化所有内容,而不需要需要嵌套的字符串。 因此,

如果我可以使用 preg_match_all 解决嵌套数据,否则我需要提出另一个解决方案

,例如 , 和 [ ] 。

I have virtually no experience of regx, but trying my best.

I have a string like this:

$fString = "Name=Sök,Value=2,Title=Combine me,Options=[Item1=1,Item2=2,Item3=3]";

I want to get an array looking like this:

Array[0] = "Name=Sök"
Array[1] = "Value=2"
Array[2] = "Title=Combine me"
Array[3] = "Options=[Item1=1,Item2=2,Item3=3]"

What I have managed to do so far is:

preg_match_all("/[^,]*[\w\d]*=[^,]*/",$fString,$Data);

But it I can't figure out how to fix the last "Option".

Array ( [0] => Array ( [0] => Name=S�k [1] => Value=2 [2] => Title=Combine me [3] => Options=[Item1=1 [4] => Item2=2 [5] => Item3=3] ) )

...and why is the result an array inside an array?!?


[EDIT]

I guess I need to explain the whole idea of what I'm trying to do here, I'm not sure I'm on the right track any more.

I have created some classes where I store all the "persistent" variables in an array. I have a function that serializes this array so I can be stored in a database.

I know all about the serialize() function, but I'm doing some filtering so I can't use it as it is, and I also prefer to have it more readable for manual editing. This array can have nested arrays within, that needs to be preserved. When I read it all back from the database, the original array must be created again.

I had it all working with the eval() command but stumbled into trouble where I had nested arrays because of the " or ' characters was breaking the main outer string. So this approach was an attempt to serialize everything without nested strings that needed to be preserved.

So if I can solve the nested data with preg_match_all I'm there, otherwise I need to come up with another solution.

I guess the data needs to be escaped as well, such as the , and [ ]

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

弥繁 2024-10-18 13:23:23

这是一个基本上可以完成您需要的功能:

function explode_me($str) {
    $a = array();
    $v = "";
    $ignore = false;
    for ($i = 0; $i < strlen($str); $i++) {
        if ($str[$i] == ',' && !$ignore) {
            $a[] = $v;
            $v = "";
        }
        else if ($str[$i] == '[' && !$ignore) {
            $ignore = true;
            $v .= $str[$i];
        }
        else if ($str[$i] == ']' && $ignore) {
            $ignore = false;
            $v .= $str[$i];
        }
        else {
            $v .= $str[$i];
        }
    }
    $a[] = $v;
    return $a;
}

测试它:

$str = "Name=Sök,Value=2,Title=Combine me,Options=[Item1=1,Item2=2,Item3=3]";
$a = explode_me($str);

print_r($a);

打印:

Array
(
    [0] => Name=Sök
    [1] => Value=2
    [2] => Title=Combine me
    [3] => Options=[Item1=1,Item2=2,Item3=3]
)

Here is a function that will do basically what you need:

function explode_me($str) {
    $a = array();
    $v = "";
    $ignore = false;
    for ($i = 0; $i < strlen($str); $i++) {
        if ($str[$i] == ',' && !$ignore) {
            $a[] = $v;
            $v = "";
        }
        else if ($str[$i] == '[' && !$ignore) {
            $ignore = true;
            $v .= $str[$i];
        }
        else if ($str[$i] == ']' && $ignore) {
            $ignore = false;
            $v .= $str[$i];
        }
        else {
            $v .= $str[$i];
        }
    }
    $a[] = $v;
    return $a;
}

To test it:

$str = "Name=Sök,Value=2,Title=Combine me,Options=[Item1=1,Item2=2,Item3=3]";
$a = explode_me($str);

print_r($a);

which prints:

Array
(
    [0] => Name=Sök
    [1] => Value=2
    [2] => Title=Combine me
    [3] => Options=[Item1=1,Item2=2,Item3=3]
)
爱她像谁 2024-10-18 13:23:23
(\w+)=(\[[^\]]+\]|[^,]+)

这可以分解为:

(\w+)        # a word (store in match group 1)
=            # the "=" character
(            # begin match group 2
  \[         #   a "[" character
  [^\]]+     #   anything but "]" character
  \]         #   a "]" character
  |          #   or...
  [^,]+      #   anything but a comma
)            # end match group 1

使用 preg_match_all() 应用:

$fString = "Name=Sök,Value=2,Title=Combine me,Options=[Item1=1,Item2=2,Item3=3]";

$matches = array();
preg_match_all("/(\\w+)=(\\[[^\\]]+\\]|[^,]+)/", $fString, $matches);

这会产生比您想要的更详细的结果:

Array
(
    [0] => Array
        (
            [0] => Name=Sök
            [1] => Value=2
            [2] => Title=Combine me
            [3] => Options=[Item1=1,Item2=2,Item3=3]
        )

    [1] => Array
        (
            [0] => Name
            [1] => Value
            [2] => Title
            [3] => Options
        )

    [2] => Array
        (
            [0] => Sök
            [1] => 2
            [2] => Combine me
            [3] => [Item1=1,Item2=2,Item3=3]
        )

)

$result[0] 就是您想要的。 $result[1]$result[2] 分别是属性名称和值,这使您能够立即使用它们,而不需要执行额外的步骤来拆分诸如“Options=[Item1=1,Item2=2,Item3=3]” 位于正确的 = 处。

(\w+)=(\[[^\]]+\]|[^,]+)

This breaks down as:

(\w+)        # a word (store in match group 1)
=            # the "=" character
(            # begin match group 2
  \[         #   a "[" character
  [^\]]+     #   anything but "]" character
  \]         #   a "]" character
  |          #   or...
  [^,]+      #   anything but a comma
)            # end match group 1

Apply with preg_match_all():

$fString = "Name=Sök,Value=2,Title=Combine me,Options=[Item1=1,Item2=2,Item3=3]";

$matches = array();
preg_match_all("/(\\w+)=(\\[[^\\]]+\\]|[^,]+)/", $fString, $matches);

Which results in something even more detailed than you wanted to have:

Array
(
    [0] => Array
        (
            [0] => Name=Sök
            [1] => Value=2
            [2] => Title=Combine me
            [3] => Options=[Item1=1,Item2=2,Item3=3]
        )

    [1] => Array
        (
            [0] => Name
            [1] => Value
            [2] => Title
            [3] => Options
        )

    [2] => Array
        (
            [0] => Sök
            [1] => 2
            [2] => Combine me
            [3] => [Item1=1,Item2=2,Item3=3]
        )

)

$result[0] is what you wanted. $result[1] and $result[2] are property names and values separately, which enables you to use them right away instead of making an extra step that splits things like "Options=[Item1=1,Item2=2,Item3=3]" at the correct =.

牵你手 2024-10-18 13:23:23

如果您可以更改项目之间的分隔符(其中显示 Item1=1,Item2=2,Item3=3 为 Item1=1|Item2=2|Item3=3 之类的内容),您可以轻松使用 explode(', ',$fString) 将字符串转换为数组。

我还可以提供这段代码来更改分隔符,因为我没有使用正则表达式的经验:

$newstr = str_replace(',Item','|Item',$fString);
$newarray = explode(',',$newstr);

$newarray 看起来像这样:

Array[0] = "Name=Sök"
Array[1] = "Value=2"
Array[2] = "Title=Combine me"
Array[3] = "Options=[Item1=1|Item2=2|Item3=3]"

If you could change the separators between the items (where it says Item1=1,Item2=2,Item3=3 to something like Item1=1|Item2=2|Item3=3) you could easily use explode(',',$fString) to convert a string to an array.

I can also offer this piece of code that will change the separators, as I have no experience with regex:

$newstr = str_replace(',Item','|Item',$fString);
$newarray = explode(',',$newstr);

$newarray will look like this:

Array[0] = "Name=Sök"
Array[1] = "Value=2"
Array[2] = "Title=Combine me"
Array[3] = "Options=[Item1=1|Item2=2|Item3=3]"
陌若浮生 2024-10-18 13:23:23

这个问题更适合解析而不是正则表达式提取。您可以将特殊情况分开以使其工作:

preg_match_all("/(\w+)=( \w[^,]+ | \[[^\]]+\] )/x", $str, $m);
$things = array_combine($m[1], $m[2]);

将为您提供一个 PHP 变量,例如(但您可以访问 $m[0] 来获取未解析的字符串):

[Name] => Sök
[Title] => Combine me
[Options] => [Item1=1,Item2=2,Item3=3]

您可以在 Options 上重新应用该函数那个也爆炸吧

技巧再次是区分 \w 以字母开头的任何内容和 \[...\] 包含的选项。在那里,您必须使其与所有非右括号匹配 ^] ,仅此而已。

This is a problem that lends itself more to parsing than regex extraction. Bout you can separate the special case to make it work:

preg_match_all("/(\w+)=( \w[^,]+ | \[[^\]]+\] )/x", $str, $m);
$things = array_combine($m[1], $m[2]);

Will give you a PHP variable like (but you can access $m[0] for the unparsed strings):

[Name] => Sök
[Title] => Combine me
[Options] => [Item1=1,Item2=2,Item3=3]

You can reapply the function on Options to explode that too.

The trick again is differentiating between \w anything that starts with a letter, and the \[...\] enclosed options. There you have to just make it match ^] all non-closing-brackets, and that's it.

初见你 2024-10-18 13:23:23

所以,这是另一种方法。它是一个用于嵌套结构的迷你解析器。如果您需要转义码,请调整正则表达式。

function parse(&$s) {
    while (strlen($s) && preg_match("/^(.*?)([=,\[\]])/", $s, $m)) {
        $s = substr($s, 1 + strlen($m[1]));
        switch ($m[2]) {
            case "=":
               $key = $m[1];
               break;
            case ",":
               if (!isset($r[$key])) {
                  $r[$key] = $m[1];
               }
               break;
            case "[":
               $r[$key] = parse($s);
               break;
            case "]":
               return $r;
        }
    }
    if ($s) { $r[$key] = $s; } // remainder
    return $r;
}

So, here is another approach. It's a mini parser for nested structures. Adapt the regex if you need escape codes.

function parse(&$s) {
    while (strlen($s) && preg_match("/^(.*?)([=,\[\]])/", $s, $m)) {
        $s = substr($s, 1 + strlen($m[1]));
        switch ($m[2]) {
            case "=":
               $key = $m[1];
               break;
            case ",":
               if (!isset($r[$key])) {
                  $r[$key] = $m[1];
               }
               break;
            case "[":
               $r[$key] = parse($s);
               break;
            case "]":
               return $r;
        }
    }
    if ($s) { $r[$key] = $s; } // remainder
    return $r;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文