【问题标题】:Regex to match a string that contains substrings separated with dots正则表达式匹配包含用点分隔的子字符串的字符串
【发布时间】:2021-04-18 16:24:35
【问题描述】:

我需要使用点符号从数组中获取一个值。例如:

$arr = [
    'first' => [
        'second' => [
            'third' => 'hello'
        ]
    ]
];

$value = array_dot($arr, 'first.second.third'); // returns "hello"

所以我需要做的是检查它是否是一个有效的字符串,我们可以通过它从数组中获取一个值。

约束:

  • 仅限非空白字符
  • 至少包含一个点
  • 不能以点开头或结尾
  • 每个点之前和之后都必须有一个非点子字符串

案例:

`value.inside.array` valid
`val-2.of.array` valid
`.var2.in.arr` invalid
`dot.notation.` invalid
`value. dot` invalid
`consecutive....dots` invalid

【问题讨论】:

  • consecutive....dots 应该是有效路径吗?
  • @mickmackusa no.

标签: php regex validation


【解决方案1】:

据我所知,一条有效的路径将从一个或多个非点开始,然后是一个或多个点序列,然后是一个或多个非点(根据需要重复到最后字符串)。

这是正则表达式模式中的逻辑。

代码:(Demo)

$array = [
    "value.inside.array",
    "val-2.of.array",
    ".var2.in.arr",
    "dot.notation.",
    "value. dot",
    "consecutive....dots",
    "a.b.c.d.e.f"
];

var_export(
    preg_grep('~^[^.\s]+(?:\.[^.\s]+)+$~', $array)
);

输出:

array (
  0 => 'value.inside.array',
  1 => 'val-2.of.array',
  6 => 'a.b.c.d.e.f',
)

或者允许使用这种模式的连续点:(Demo)

~^[^.\s]+\.\S*[^.\s]$~

【讨论】:

  • 避免连续的点非常有意义@mickmackusa!
  • 我不完全确定。数组键可以为空。 3v4l.org/uloop这可能是 OP 的主观决定。
  • 我赞成这个答案,因为它正确处理所有边缘情况(与接受的解决方案不同)。
【解决方案2】:

试试这个:

^[^.\s]\S*\.\S*[^.\s]$

解释:

^[^.\s]     Start with any non-dot and non-white character
\S*             Any non space characters
\.              Force at least one dot
\S*             Any non space characters
[^.\s]$    End with any non-dot and non-white character

演示here.

【讨论】:

  • 在此演示中将您的输出与我的输出进行比较:3v4l.org/hplm8
  • 我从大家那里得到了很好的答案,但不知怎的,我最喜欢这个。干杯。
【解决方案3】:

我会在这里使用preg_match_all 和适当的正则表达式模式。我们可以首先使用implode() 形成所有输入项的空格分隔的单个字符串。然后,使用正则表达式 match all 来找出匹配项。

$array = ["value.inside.array", "val-2.of.array", ".var2.in.arr", "dot.notation.", "value. dot"];
$input = implode(" ", $array);
preg_match_all("/(?<!\S)[^.\s]\S*\.\S*[^.\s](?!\S)/", $input, $matches);
print_r($mstches[0]);

打印出来:

Array
(
    [0] => value.inside.array
    [1] => val-2.of.array
)

下面是正则表达式模式的解释:

(?<!\S) assert that what precedes is either whitespace or the start of the string
[^.\s]  first character is non whitespace other than dot
\S*     match zero or more non whitespace characters
\.      match a dot
\S*     match zero or more non whitespace characters
[^.\s]  final character is non whitespace other than dot
(?!\S)  assert that what follows is either whitespace or the start of the string

【讨论】:

  • 成为或不成为....是个问题。
  • @mickmackusa 不,它是数组的点表示法,在 Laravel 中常用,就像关联数组中键的访问器。
  • @Amir 如果答案是No,那么其他两个答案在所有情况下都不会为您服务,我的答案是页面上唯一正确的答案,而您接受了错误的答案。
猜你喜欢
  • 2016-04-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-08
  • 1970-01-01
  • 1970-01-01
  • 2014-10-22
  • 1970-01-01
相关资源
最近更新 更多