Regex to add spacing between sentences in a string in php - php

I use a spanish dictionary api that returns definitions with small issues. This specific problem happens when the definition has more than 1 sentence. Sometimes the sentences are not properly separated by a space character, so I receive something like this:
This is a sentence.Some other sentence.Sometimes there are no spaces between dots. See?
Im looking for a regex that would replace "." for ". " when the dot is immediately followed by a char different than the space character. The preg_replace() should return:
This is a sentence. Some other sentence. Sometimes there are no spaces between dots. See?
So far I have this:
echo preg_replace('/(?<=[a-zA-Z])[.]/','. ',$string);
The problem is that it also adds a space when there is already a space after the dot. Any ideas? Thanks!

Try this regular expression:
echo preg_replace('/(?<!\.)\.(?!(\s|$|\,|\w\.))/', '. ', $string);

echo preg_replace( '/\.([^, ])/', '. $1', $string);
It works!

You just need to apply a look-ahead to so adds a space if the next character is something other than a space or is not the end of the string:
$string = preg_replace('/(?<=[a-zA-Z])[.](?![\s$])/','. ',$string);

Related

Preg_replace Tag Replace Dashes With HTML Tag

I am partially disabled. I write a LOT of wordpress posts in 'text' mode and to save typing I will use a shorthand for emphasis and strong tags. Eg. I'll write -this- for <em>this</em>.
I want to add a function in wordpress to regex replace word(s) that have a pair of dashes with the appropriate html tag. For starters I'd like to replace -this- with <em>this</em>
Eg:
-this- becomes <em>this</em>
-this-. becomes <em>this</em>.
What I can't figure out is how to replace the bounding chars. I want it to match the string, but then retain the chars immediately before and after.
$pattern = '/\s\-(.*?)\-(\s|\.)/';
$replacement = '<em>$1</em>';
return preg_replace($pattern, $replacement, $content);
...this does the 'search' OK, but it can't get me the space or period after.
Edit: The reason for wanting a space as the beginning boundary and then a space OR a period OR a comma OR a semi-colon as the ending boundary is to prevent problems with truly hyphenated words.
So pseudocode:
1. find the space + string + (space or punctuation)
2. replace with space + open_htmltag + string + close_htmltag + whatever the next char is.
Ideas?
a space as the beginning boundary and then a space OR a period OR a comma OR a semi-colon as the ending boundary
You can try with capturing groups with <em>$1</em>$2 as substitution.
[ ]-([^-]*)-([ .,;])
DEMO
sample code:
$re = "/-([^-]*)-([ .,;])/i";
$str = " -this-;\n -this-.\n -this- ";
$subst = '<em>$1</em>$2';
$result = preg_replace($re, $subst, $str);
Note: Use single space instead of \s that match any white space character [\r\n\t\f ]
Edited by o/p: Did not need opening space as delimiter. This is the winning answer.
You can try with Positive Lookahead as well with only single capturing group.
-([^-]*)-(?=[ .,;])
substitution string: <em>$1</em>
DEMO
You can use this regex:
(-)(.*?)(-)
Check the substitution section:
Working demo
Edit: as an improvement you can also use -(.*?)- and utilize capturing group \1
In the code below, the regex pattern will start at a hyphen and collect any non-hyphen characters until the next hyphen occurs. It then wraps the collected text in an em tag. The hyphens are discarded.
Note: If you use a hyphen for its intended purposes, this may cause problems. You may want to devise an escape character for that.
$str = "hello -world-. I am -radley-.";
$replace = preg_replace('/-([^-]+?)-/', '<em>$1</em>', $str);
echo $str; // no formatting
echo '<br>';
echo $replace; // formatting
Result:
hello -world-. I am -radley-.
hello <em>world</em>. I am <em>radley</em>.

Normalize spaces in a string?

I need to normalize the spaces in a string:
Remove multiple adjacent spaces
Remove spaces at the beginning and end of the string
E.g. " my name is " => my name is
I tried
str_replace(' ',' ',$str);
I also tried php Replacing multiple spaces with a single space but that didn't work either.
Replace any occurrence of 2 or more spaces with a single space, and trim:
$str = preg_replace('/ {2,}/', ' ', trim($input));
Note: using the whitespace character class \s here is a fairly bad idea since it will match linebreaks and other whitespace that you might not expect.
Use a regex
$text = preg_replace("~\\s{2,}~", " ", $text);
The \s approach strips away newlines too, and / {2,}/ approach ignores tabs and spaces at beginning of line right after a newline.
If you want to save newlines and get a more accurate result, I'd suggest this impressive answer to similar question, and this improvement of the previous answer. According to their note, the answer to your question is:
$norm_str = preg_replace('/[^\S\r\n]+/', ' ', trim($str));
In short, this is taking advantage of double negation. Read the links to get an in-depth explanation of the trick.

preg_replace to remove stand-alone numbers

I'm looking to replace all standalone numbers from a string where the number has no adjacent characters (including dashes), example:
Test 3 string 49Test 49test9 9
Should return Test string 49Test 49Test9
So far I've been playing around with:
$str = 'Test 3 string 49Test 49test9 9';
$str= preg_replace('/[^a-z\-]+(\d+)[^a-z\-]+?/isU', ' ', $str);
echo $str;
However with no luck, this returns
Test string 9Test 9test9
leaving out part of the string, i thought to add [0-9] to the matches, but to no avail, what am I missing, seems so simple?
Thanks in advance
Try using a word boundary and negative look-arounds for hyphens, eg
$str = preg_replace('/\b(?<!-)\d+(?!-)\b/', '', $str);
Not that complicated, if you watch the spaces :)
<?php
$str = 'Test 3 string 49Test 49test9 9';
$str = preg_replace('/(\s(\d+)\s|\s(\d+)$|^(\d+)\s)/iU', '', $str);
echo $str;
Try this, I tried to cover your additional requirement to not match on 5-abc
\s*(?<!\B|-)\d+(?!\B|-)\s*
and replace with a single space!
See it here online on Regexr
The problem then is to extend the word boundary with the character -. I achieved this by using negative look arounds and looking for - or \B (not a word boundary)
Additionally I am matching the surrounding whitespace with the \s*, therefore you have to replace with a single space.
I would suggest using
explode(" ",$str)
to get an array of the "words" in your string. Then it should be easier to filter out single numbers.

How to replace one or more consecutive spaces with one single character?

I want to generate the string like SEO friendly URL. I want that multiple blank space to be eliminated, the single space to be replaced by a hyphen (-), then strtolower and no special chars should be allowed.
For that I am currently the code like this:
$string = htmlspecialchars("This Is The String");
$string = strtolower(str_replace(htmlspecialchars((' ', '-', $string)));
The above code will generate multiple hyphens. I want to eliminate that multiple space and replace it with only one space. In short, I am trying to achieve the SEO friendly URL like string. How do I do it?
You can use preg_replace to replace any sequence of whitespace chars with a dash...
$string = preg_replace('/\s+/', '-', $string);
The outer slashes are delimiters for the pattern - they just mark where the pattern starts and ends
\s matches any whitespace character
+ causes the previous element to match 1 or more times. By default, this is 'greedy' so it will eat up as many consecutive matches as it can.
See the manual page on PCRE syntax for more details
echo preg_replace('~(\s+)~', '-', $yourString);
What you want is "slugify" a string. Try a search on SO or google on "php slugify" or "php slug".

regex: delete white characters

I try to delete more then one white characters from my string:
$content = preg_replace('/\s+/', " ", $content); //in some cases it doesn't work
but when i wrote
$content = preg_replace('/\s\s+/', " ", $content); //works fine
could somebody explain why?
because when i write /\s+/ it must match all with one or more white character, why it doesn't work?
Thanks
What is the minimum number of whitespace characters you want to match?
\s+ is equivalent to \s\s* -- one mandatory whitespace character followed by any number more of them.
\s\s+ is equivalent to \s\s\s* -- two mandatory whitespace characters followed by any number more (if this is what you want, it might be clearer as \s{2,}).
Also note that $content = preg_replace('/\s+/', " ", $content); will replace any single spaces in $content with a single space. In other words, if your string only contains single spaces, the result will be no change.
I just wanted to add to that the reason why your /s+/ worked sometimes and not others, is that regular expressions are very greedy, so it is going to try to match one or more space characters, and as many as it can match. I think that is where you got tripped up in finding a solution.
Sorry I'm not yet able to add comments, or I would have just added this comment to Daniel's answer, which is good.
Are you using the Ungreedy option (/U)? It doesn't say so in your code, but if so, it would explain why the first preg_replace() is replacing each single space with a single space (no change). In that case, the second preg_replace() would be replacing each double space with a single space. If you try the second one on a string of four spaces and the result is a double space, I would suspect ungreediness.
try preg_replace("/([\s]{2,})/", " ", $text)

Categories