Мне нужно получить значение из массива, используя точечную нотацию. Например:

$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
1
Amir Rami 13 Янв 2021 в 19:08

3 ответа

Лучший ответ

Попробуй это:

^[^.\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

Демо-версия здесь.

1
kaza 13 Янв 2021 в 16:34

Насколько я понимаю, действительный путь начинается с одной или нескольких точек, не являющихся точками, затем за ними следуют одна или несколько последовательностей точки, затем одна или несколько точек, не являющихся точками (при необходимости повторяются до конца строки. ).

Вот эта логика в шаблоне регулярного выражения.

Код: (Демо)

$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',
)

Или разрешите следующие друг за другом точки с этим шаблоном: (Демо)

~^[^.\s]+\.\S*[^.\s]$~
3
mickmackusa 13 Янв 2021 в 17:46

Я бы использовал здесь 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
1
Tim Biegeleisen 13 Янв 2021 в 16:23
65705621