You can use
preg_replace('~(?<!\\\\)(?:\\\\{2})*(?:"[^"\\\\]*(?:\\\\.[^"\\\\]*)*"|\'[^\'\\\\]*(?:\\\\.[^\'\\\\]*)*\')(*SKIP)(?!)|\s+~s', '', $str)
See the PHP demo and a regex demo.
Details
(?<!\\)(?:\\{2})*
- a check if there is no escaping\
immediately on the left: any amount of double backslashes not preceded with\
(?:"[^"\\]*(?:\\.[^"\\]*)*"'[^'\\]*(?:\\.[^'\\]*)*')
- either a double- or single-quoted string literal allowing escape sequences(*SKIP)(?!)
- skip the match and start a new search from the location where the regex failed
- or\s+
- 1 or more whitespaces.Note that a backslash in a single-quoted PHP string literal is used to form string escape sequences, and thus a literal backslash is "coded" with the help of double backslashes, and to match a literal backslash in text, two such backslashes are required, hence"\\\\"
is used.
You could capture either"
or'
in a group and consume any escaped variants or each until encountering the closing matching'
or"
using a backreference\1
(?<!\\)(['"])(?:(?!(?:\1\\)).\\.)*+\1(*SKIP)(*FAIL)\h+
Explanation
(?<!\\)
Negative lookbehind, assert not a\
directly to the left(['"])
capture group 1, match either'
or"
(?:
Non capture group
(?!(?:\1\\)).
If what is not directly to the right is either the value in group 1 or a backslash, match any char except a newline
Or\\.
Match an escaped character)*+
Close non capture group and repeat 1+ times\1
Backreference to what is captured in group 1 (match up either'
or"
)(*SKIP)(*FAIL)
Skip the match until now. Read more about (*SKIP)(*FAIL)
Or\h+
Match 1+ horizontal whitespace chars that you want to removeAs @Wiktor Stribiżew points out in his comment
In some rare situations, this might match at a wrong position, namely, if there is a literal backslash (not an escaping one) before a single/double quoted string that should be skipped. You need to add (?:\{2})* after (?<!\)
The pattern would then be:
(?<!\\)(?:\\{2})*(['"])(?:(?!(?:\1\\)).\\.)*+\1(*SKIP)(*FAIL)\h+
Here is a 3 step approach:
$str = 'abc | xx ?? "1 x \' 3" d e f \' y " 5 \' x yz';
echo 'input: ' . $str . "\n";
$result = preg_replace_callback( // replace spaces in quote sections with placeholder
'|(["\'])(.*?)(\1)|',
function ($matches) {
$s = preg_replace('/ /', "\x01", $matches[2]);
return $matches[1] . $s . $matches[3];
},
$str
);
$result = preg_replace('/ /', '', $result); // remove all spaces
$result = preg_replace('/\x01/', ' ', $result); // restore spaces in quote sections
echo 'result: ' . $result;
echo "\nexpect: " . 'abc|xx??"1 x \' 3"def\' y " 5 \'xyz';
Output:
input: abc | xx ?? "1 x ' 3" d e f ' y " 5 ' x yz
result: abc|xx??"1 x ' 3"def' y " 5 'xyz
expect: abc|xx??"1 x ' 3"def' y " 5 'xyz
Explanation:
preg_replace_callback()
'|(["\'])(.*?)(\1)|'
matches quote sections starting and ending with either"
or'
(\1)
makes sure to match the closing quote (either"
or'
)preg_replace()
to replace all spaces with a non-printable replacement"\x01"
preg_replace()
to remove all spaces"\x01"
, thus misses spaces in quote sectionspreg_replace()
to restore all spaces from replacement"\x01"
Our community is visited by hundreds of web development professionals every day. Ask your question and get a quick answer for free.
Find the answer in similar questions on our website.
Do you know the answer to this question? Write a quick response to it. With your help, we will make our community stronger.
PHP (from the English Hypertext Preprocessor - hypertext preprocessor) is a scripting programming language for developing web applications. Supported by most hosting providers, it is one of the most popular tools for creating dynamic websites.
The PHP scripting language has gained wide popularity due to its processing speed, simplicity, cross-platform, functionality and distribution of source codes under its own license.
https://www.php.net/
Welcome to the Q&A site for web developers. Here you can ask a question about the problem you are facing and get answers from other experts. We have created a user-friendly interface so that you can quickly and free of charge ask a question about a web programming problem. We also invite other experts to join our community and help other members who ask questions. In addition, you can use our search for questions with a solution.
Ask about the real problem you are facing. Describe in detail what you are doing and what you want to achieve.
Our goal is to create a strong community in which everyone will support each other. If you find a question and know the answer to it, help others with your knowledge.