I have strings like this (some examples):
F7998FM3213/02F
J442554NM/05
K439459845/34D
I need to use PHP with preg_replace and regular expressions to delete all non-numeric characters in any string, after the forward-slash, '/'.
For example the codes above would look like this afterwards:
F7998FM3213/02
J442554NM/05
K439459845/34
If you're going for readability, something like this would be perfect:
$parts = explode("/",$line,2);
$parts[1] = preg_replace("/\D/","",$parts[1]);
$output = implode("/",$parts);
However, for conciseness and based entirely on the examples you have given, try this:
$output = preg_replace("/\D+$/","",$input);
This will strip any non-numeric characters from the end of the string, which seems to be what you're after based on your examples.
you can use this:
$subject = <<<LOD
F7998FM3213/02F
J442554NM/05
K439459845/34D
K439459845/34D34
LOD;
echo preg_replace('~^[^/]*+/\K|[^\d\n]++~m', '', $subject);
explanation:
The regex is an alternation between two things:
You match the begining until you encounter / included
the part after the / that is all that is not a digit or a new line one or more times
Since the begining of the string is checked at first, all non digit characters are removed after the /
To remove all \D anywhere after a / you could replace:
(?:/\K|\G(?!^))(\d*)\D+
with $1. Like:
preg_replace(',(?:/\K|\G(?!^))(\d*)\D+,', '$1', $str);
Related
I am testing RegExp with online regexr.com tool. I will test string with multiple cases, but I can't get substitution to work.
RexEx for matching string is:
/^[0-9]{1,3}[0-9]{6,7}$/
Which matches local mobile number in my country like this:
0921234567
But then I want to substitute number in this way: add "+" sign, add my country code "123", add "." sign, and then finaly, add matched number with stripped leading zero.
Final number will be:
+385.921234567
I have basic idea to insert matched string, but I am not sure how prepend characters, and strip zero from matched string in following substitution pattern:
\+$&\n\t
I will use PHP preg_replace function.
EDIT:
As someone mentioned wisely, there is posibility that there will be one, two or none of zeros, but I will create separate test cases with regex just testing number of zeroes. Doing so in one regex seems to complicated for now.
Possible numbers will be:
0921234567
00111921234567
Where 111 is country code. I know that some country codes consist of 2 or 3 digits, but I will create special cases, for most country codes.
You can use this preg_replace to strip optional zeroes from start of your mobile #:
$str = preg_replace('~^0*(\d{7,9})$~', '+385.$1', $str);
^[0-9]([0-9]{1,2}[0-9]{6,7})$
You just need to add groups.Replace by +385.$1.See demo.
https://regex101.com/r/cJ6zQ3/22
$re = "/^[0-9]([0-9]{1,2}[0-9]{6,7})$/m";
$str = "0921234567\n";
$subst = "+385.$1";
$result = preg_replace($re, $subst, $str);
I would use a 2-step solution:
Check if we match the main regex
Replace the number by pre-pending + + country code + . + number without leading zeros.
PHP code:
$re = "/^[0-9]{7,10}$/";
$str = "0921234567";
if (preg_match($re, $str, $match)) {
echo "+385." . preg_replace('/^0+/', '', $match[0]);
}
Note that splitting out character class in your regex pattern makes no sense when not using capture groups. ^[0-9]{7,10}$ is the same then as ^[0-9]{1,3}[0-9]{6,7}$, meaning match 7 to 10 digits from start to end of the string.
Leading zeros are easily trimmed from the start with /^0+/ regex.
I have three types of strings that I encounter. My goal is to cycle through all of them and just get name.
page_1.name
page_2.name.text
page_1.name.something
The only way I can figure out doing this is to first remove the page_# with the following:
$remove_page = preg_replace("/(page_\d+\.)(\w+)/", "$2", $string);
Then remove the last bit like so:
$get_name = preg_replace("/(\w+)(\.\w+)/", "$1", $remove_page);
Is there a more efficient way to do this? This works, but I feel like I'm only slightly grasping the power of regex.
You can use this regex:
preg_match('/(?<=page_\d\.)[^.]+/', $input, $matches);
(?<=page_\d\.) is a lookbehind that makes sure our match is preceded by page_ and a digit. [^.]+ will match 1 or more characters that are not DOT.
RegEx Demo
Otherwise split by DOT and take 1st element:
$arr = explode('.', $input);
$name = $arr[1];
$str="Your LaTeX document can \DIFaddbegin \DIFadd{test}\DIFaddend be easily
and the text can have multiple lines in it like this\DIFaddbegin \DIFadd{test2}
\DIFaddend"
I need to convert all \DIFaddbegin \DIFadd{test}\DIFaddend to \added{test}.
I tried
$o= preg_replace_callback('/\\DIFaddbegin\\s\DIFadd{(.*?)}\\DIFaddend/',
function($m) {return preg_replace('/$m[0]/','\added{$m[1]}',$m[0]);},$str);
But no luck. Which would be correct pattern for this? And also even if the string contains new line character the pattern should work.
You don't need a callback, using preg_replace() is fine for this task. To match a single backslash you need to double escape it meaning \\\\. To match possible whitespace between each substring, you can use \s* meaning whitespace "zero or more" times.
$str = preg_replace('~\\\\DIFaddbegin\s*\\\\DIFadd({[^}]*})\s*\\\\DIFaddend~', '\added$1', $str);
Try this:
$new_str = preg_replace("/\\\\DIFaddbegin \\\\DIFadd\{(.*)\}\\\\DIFaddend/s","\\added{\$1}",$str);
I'm attempting to remove noise words from a string, and I have what I believe is a good algorithm for it, but I'm running into a snag. Before I do my preg_replace I remove all punctuation except apostrophe ('). The I put it through this preg_replace:
$content = preg_replace('/\b('.implode('|', self::$noiseWords).')\b/','',$content);
Which works great, except for words that do indeed have that ' character. preg_replace seems to be treating that as a boundary character. This is a problem for me.
Is there a way I can get around this? A different solution perhaps?
Thanks!
Here is the example I'm using:
$content = strtolower(strip_tags($content));
$content = preg_replace("/(?!['])\p{P}/u", "", $content);// remove punctuation
echo $content;// i've added striptags for editing as well should still workyep it doesnbsp
$content = preg_replace("/\b(?<')(".implode('|', self::$noiseWords).")(?!')\b/",'',$content);
$contentArray = explode(" ", $content);
print_r($contentArray);
On the 3rd line you'll see the comment of what $content is right before the preg_replace
And though I'm assuming you can guess what my noiseWords array looks like, here's just a small fraction of it:
$noiseWords = array("a", "able","about","above","abroad","according","accordingly","across",
"actually","adj","after","afterwards","again",......)
You can use a negative lookbehind and positive lookahead to make sure you're not "around" a quote character:
$regex = "/\b(?<!')(".implode('|', self::$noiseWords).")(?!')\b/";
Now, your regex will not match anything that is preceded by or following with a single quote.
I don't know how to do the following:
find all instances of '/\s[2-9]\)/' and replace the space with a <br /> tag.
Something as simple as this doesn't work:
$preg_num = ' /\s[2-9]\)/';
$preg_fix = "'/<br>/[2-9]\)'";
preg_replace($preg_num,$preg_fix,$notes);
What do I need to change the $preg_fix variable to?
Using a lookahead is simpler than a backreference, IMHO.
$preg_num = '/\s(?=[2-9]\))/';
$preg_fix = '<br/>';
preg_replace($preg_num,$preg_fix,$notes);
This way, you are only replacing the space with the <br/>.
The replacement string is not treated as a regex — it is more like a literal string. If you are trying to put whatever digit [2-9] that was matched in the original regex into the replacement string, capture the character as a group and use a backreference.
$preg_num = '/\s([2-9])\)/';
$preg_fix = "<br />$1)'";
preg_replace($preg_num,$preg_fix,$notes);
For more information:
preg_replace's replacement parameter documentation
Regular expression grouping: "Use Round Brackets for Grouping"