If given [name=anystring]
or #anystring
where anystring
is a string which has already had any whitespace removed, I wish to return anystring
.
Before attempting both, I successfully performed them individually.
$pattern = "/^#(.+)$/";
preg_match($pattern, '#anystring', $matches);
preg_match($pattern, '[name=anystring]', $matches);
$pattern = "/^\\[name=(.+)\\]$/";
preg_match($pattern, '#anystring', $matches);
preg_match($pattern, '[name=anystring]', $matches);
And then I tried to combine them.
# with start ^ and end $ on both
$pattern = "/^#(.+)$|^\\[name=(.+)\\]$/";
preg_match($pattern, '#anystring', $matches);
preg_match($pattern, '[name=anystring]', $matches);
# without start ^ and end $ on both
$pattern = "/^#(.+)|\\[name=(.+)\\]$/";
preg_match($pattern, '#anystring', $matches);
preg_match($pattern, '[name=anystring]', $matches);
While I "kind of" get what I am looking for, the second pattern [name=(.+)]
returns an array with three elements.
Should I have and end $
after the first pattern and a start ^
before the second pattern? Can this result in the second pattern returning an array with three elements?
EDIT. Show how one version displays more array elements
<?php
$pattern = "/^(?:#(.+)|\\[name=(.+)\\])$/s";
preg_match($pattern, '#anystring', $matches);
print_r($matches);
preg_match($pattern, '[name=anystring]', $matches);
print_r($matches);
(
[0] => #anystring
[1] => anystring
)
Array
(
[0] => [name=anystring]
[1] =>
[2] => anystring
)
You are looking for a branch reset group where numbering of capturing groups begins from the last ID before the group:
^(?|#(.+)|\[name=(.+)])$
^^
See the regex demo
Details
^
- start of string(?|
- start of the branch reset group#(.+)
- a #
and then Group 1 capturin 1+ chars, as many as possible|
- or\[name=
- a [name=
substring(.+)
- Group 1 (again) matching 1+ chars other than line break chars, as many as possible]
- a ]
)
- end of the branch reset group$
- end of string.You can combine 2 regexes using a non capturing group:
(?:pattern1|pattern2)
I wrote this regex which will capture on both strings:
(?:\[\w+=(?<bracketword>\w+)\]|\#(?<word>\w+))
Your match will either have array key bracketword, or word. Check it out on the regex101 link below.
https://regex101.com/r/AmgHTS/1/
You can also use start and end string ^ and $ if you like. In my edited regex, my test string is two lines (one for each string), so i had to use the multi line flag too.
To capture only anything
with both use Lookbehind
like this :
(?<=#|name=)([^\[#\]]+)
https://regex101.com/r/AmgHTS/4/
for more check :