PHP preg_replace skipping where match overlaps

帅比萌擦擦* 提交于 2021-02-05 12:20:08

问题


I've been Googling this regex behavior all afternoon.

$str = ' b c d w i e f g h this string';

echo preg_replace('/\s[bcdefghjklmnopqrstuvwxyzBCDEFGHJKLMNOPQRSTUVWXYZ]{1}\s/', ' ', $str);

I want to remove all instances of a single character by itself (except for A and I) and leave one space in its place. This code appears to work on every other match. I suspect this is because the matches overlap each other.

I suspect a lookaround would be appropriate here, but I've never used them before and could use a snippet.

EDIT: Just to avoid confusion about what I am trying to accomplish. I want to turn the above string into this:

$str = ' i this string';

Notice all single-letter characters that are NOT "A" or "I" have been removed.


回答1:


You can try this:

/(?<=\s)[b-hj-zB-HJ-Z](?=\s)/

or modify the ranges if you dont need both i and I.




回答2:


You can use look-arounds instead. They are 0-length matches, and hence would not consume spaces. And {1} is really absurd there, you can remove it.

echo preg_replace('/(?<=\s)[bcdefghjklmnopqrstuvwxyzBCDEFGHJKLMNOPQRSTUVWXYZ](?=\s)/', '', $str)

You can make use of range and case-insensitive flag (?i) here, to reduce the pain of typing all those characters:

echo preg_replace('/(?i)(?<=\s)[B-HJ-Z](?=\s)/', '', $str)

or word boundaries will also work here:

echo preg_replace('/(?i)\b[B-HJ-Z]\b/', '', $str)



回答3:


You can use this:

echo preg_replace('~(?i)\b[B-HJ-Z]\b~', ' ', $str);

Notice: instead of using spaces to delimit the single letter, I use word boundaries which are the zero width limit between a character from [a-zA-Z0-9_] and another character. This is more general than a space and include (for example) punctuation symbols.



来源:https://stackoverflow.com/questions/17958236/php-preg-replace-skipping-where-match-overlaps

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!