I would like to pass characters like A,B,C,D like this to a preg_match function in PHP.
Eg >
if (preg_match ("/^SEQRES.*\s$char\s.*/", $amino)) ;
I would like to pass A,B,C,D to $char and loop through the match.
please give me a solution.
Just use string concatenation:
$re = "/^SEQRES.*\s" . $char . "\s.*/";
if (preg_match($re, $amino))
....
There is no need for a loop. Simply replace $char with "[A-D]";. Since you have bounded it by spaces, it will match one single character in the class [A-D] between spaces .
if (preg_match ("/^SEQRES.*\s[A-D]\s.*/", $amino)) ;
You may also wish to use preg_match_all().
Use preg_quote if you are getting the character from user input:
$re = "/^SEQRES.*\s" . preg_quote($char) . "\s.*/";
Related
Given an address stored as a single string with newlines delimiting its components like:
1 Street\nCity\nST\n12345
The goal would be to replace all newline characters except the first one with spaces in order to present it like:
1 Street
City ST 12345
I have tried methods like:
[$street, $rest] = explode("\n", $input, 2);
$output = "$street\n" . preg_replace('/\n+/', ' ', $rest);
I have been trying to achieve the same result using a one liner with a regular expression, but could not figure out how.
I would suggest not solving this with complicated regex but keeping it simple like below. You can split the string with a \n, pop out the first split and implode the rest with a space.
<?php
$input = explode("\n","1 Street\nCity\nST\n12345");
$input = array_shift($input) . PHP_EOL . implode(" ", $input);
echo $input;
Online Demo
You could use a regex trick here by reversing the string, and then replacing every occurrence of \n provided that we can lookahead and find at least one other \n:
$input = "1 Street\nCity\nST\n12345";
$output = strrev(preg_replace("/\n(?=.*\n)/", " ", strrev($input)));
echo $output;
This prints:
1 Street
City ST 12345
You can use a lookbehind pattern to ensure that the matching line is preceded with a newline character. Capture the line but not the trailing newline character and replace it with the same line but with a trailing space:
preg_replace('/(?<=\n)(.*)\n/', '$1 ', $input)
Demo: https://onlinephp.io/c/5bd6d
You can use an alternation pattern that matches either the first two lines or a newline character, capture the first two lines without the trailing newline character, and replace the match with what's captured and a space:
preg_replace('/(^.*\n.*)\n|\n/', '$1 ', $input)
Demo: https://onlinephp.io/c/2fb2f
I leave you another method, the regex is correct as long as the conditions are met, in this way it always works
$string=explode("/","1 Street\nCity\nST\n12345");
$string[0]."<br>";
$string[1]." ".$string[2]." ".$string[3]
I'm doing str_replace on a very long string and my $search is an array.
$search = array(
" tag_name_item ",
" tag_name_item_category "
);
$replace = array(
" tag_name_item{$suffix} ",
" tag_name_item_category{$suffix} "
);
echo str_replace($search, $replace, $my_really_long_string);
The reason why I added spaces on both $search and $replace is because I want to only match whole words. As you would have guessed from my code above, if I removed the spaces and my really long string is:
...
tag_name_item ...
tag_name_item_category ...
...
Then I would get something like
...
tag_name_item_sfx ...
tag_name_item_sfx_category ...
...
This is wrong because I want the following result:
...
tag_name_item_sfx ...
tag_name_item_category_sfx ...
...
So what's wrong?
Nothing really, it works. But I don't like it. Looks dirty, not well coded, inefficient.
I realized I can do something like this using regular expressions using the \b modifier but I'm not good with regex and so I don't know how to preg_replace.
A possible approach using regular expressions would/could look like this:
$result = preg_replace(
'/\b(tag_name_item(_category)?)\b/',
'$1' . $suffix,
$string
);
How it works:
\b: As you say are word boundaries, this is to ensure we're only matching words, not word parts
(: We want to use part of our match in the replacement string (tag_name_index has to be replaced with itself + a suffix). That's why we use a match group, so we can refer back to the match in the replacement string
tag_name_index is a literal match for that string.
(_category)?: Another literal match, grouped and made optional through use of the ? operator. This ensures that we're matching both tag_name_item and tag_name_item_category
): end of the first group (the optional _category match is the second group). This group, essentially, holds the entire match we're going to replace
\b: word boundary again
These matches are replaced with '$1' . $suffix. The $1 is a reference to the first match group (everything inside the outer brackets in the expression). You could refer to the second group using $2, but we're not interested in that group right now.
That's all there is to it really
More generic:
So, you're trying to suffix all strings starting with tag_name, which judging by your example, can be followed by any number of snake_cased words. A more generic regex for that would look something like this:
$result = preg_replace(
'/\b(tag_name[a-z_]*)\b/',
'$1' . $suffix,
$string
);
Like before, the use of \b, () and the tag_name literal remains the same. what changed is this:
[a-z_]*: This is a character class. It matches characters a-z (a to z), and underscores zero or more times (*). It matches _item and _item_category, just as it would match _foo_bar_zar_fefe.
These regex's are case-sensitive, if you want to match things like tag_name_XYZ, you'll probably want to use the i flag (case-insensitive): /\b(tag_name[a-z_]*)\b/i
Like before, the entire match is grouped, and used in the replacement string, to which we add $suffix, whatever that might be
To avoid the problem, you can use strtr that parses the string only once and chooses the longest match:
$pairs = [ " tag_name_item " => " tag_name_item{$suffix} ",
" tag_name_item_category " => " tag_name_item_category{$suffix} " ];
$result = strtr($str, $pairs);
This function replaces the entire whole word but not the substring with an array element which matches the word
<?PHP
function removePrepositions($text){
$propositions=array('/\b,\b/i','/\bthe\b/i','/\bor\b/i');
if( count($propositions) > 0 ) {
foreach($propositions as $exceptionPhrase) {
$text = preg_replace($exceptionPhrase, '', trim($text));
}
$retval = trim($text);
}
return $retval;
}
?>
See the entire example
I couldn't find the solution using search.
I am looking for a php solution to remove all character BEFORE the second occurance of and underscore (including the underscore)
For example:
this_is_a_test
Should output as:
a_test
I currently have this code but it will remove everything after the first occurance:
preg_replace('/^[^_]*.s*/', '$1', 'this_is_a_test');
Using a slightly different approach,
$s='this_is_a_test';
echo implode('_', array_slice( explode( '_', $s ),2 ) );
/* outputs */
a_test
preg_replace('/^.*_.*_(.*)$/U', '$1', 'this_is_a_test');
Note the U modifier which tells regex to take as less characters for .* as possible.
You can also use explode, implode along with array_splice like as
$str = "this_is_a_test";
echo implode('_',array_splice(explode('_',$str),2));//a_test
Demo
Why go the complicated way? This is a suggestion though using strrpos and substr:
<?php
$str = "this_is_a_test";
$str_pos = strrpos($str, "_");
echo substr($str, $str_pos-1);
?>
Try this one.
<?php
$string = 'this_is_a_test';
$explode = explode('_', $string, 3);
echo $explode[2];
?>
Demo
I'm still in favor of a regular expression in this case:
preg_replace('/^.*?_.*?_/', '', 'this_is_a_test');
Or (which looks more complex here but is easily adjustable to N..M underscores):
preg_replace('/^(?:.*?_){2}/', '', 'this_is_a_test');
The use of the question mark in .*? makes the match non-greedy; and the pattern has been expanded from the original post to "match up through" the second underscore.
Since the goal is to remove text the matched portion is simply replaced with an empty string - there is no need for a capture group or to use such as the replacement value.
If the input doesn't include two underscores then nothing is removed; such can be adjusted, very easily with the second regular expression, if the rules are further clarified.
I have this code.
<?php
$USClass = "3/312";
$USClass = preg_replace_callback('~[\d.]+/[\d.]+~', function ($matches) {
$parts = explode('/', $matches[0]);
return $parts[1] . ',' . $parts[0];
}, $USClass);
echo $USClass;
?>
It prints 312,3 which is what I wanted.
However, if I give an input like D12/336 then it does not work. I want it to print 336,D12
How can I do it? and What is wrong with my current code which is not handling this Alphanumeric? Is it because I used \d ?
EDIT:
I want it to handle inputs like this as well
148/DIG.111
then the output should be DIG.111,148
Yes \d does only contain digits.
You can try \w instead this is alphanumeric, but additionally it includes also _
To be Unicode you can go for
~[\pL\d.]+/[\pL\d.]+~u
\pL is a Unicode code point with the property "Letter"
The u at the end turn on the UTF-8 mode that is needed to use this feature
See http://www.php.net/manual/en/regexp.reference.unicode.php
Other solution
I think you ar e doing this a bit complicated. It would be simplier if you would make use of capturing groups.
Try this:
$in = "148/DIG.111";
preg_match_all('~([\w.]+)/([\w.]+)~', $in, $matches);
echo $matches[2][0] . ',' . $matches[1][0];
Explanation:
([\w.]+)/([\w.]+)
^^^^^^^^ ^^^^^^^^
Group 1 Group 2
Because of the brackets the matched substring is stored in the array $matches.
See here for more details on preg_match_all
With a simple preg_replace:
$USClass = "148/DIG.111";
$USClass = preg_replace('#(.+?)/(.+)#', "$2,$1", $USClass);
echo $USClass;
output:
DIG.111,148
For example suppose I have
$blah = "C$###.a534&";
I wish to filter the string so that only letters, numbers and "." remain yielding "C.a534"
How do I do this?
If you know what characters should be allowed, you can use a negated character group (in a regular expression) to remove everything else:
$blah = preg_replace('/[^a-z0-9\.]/i', '', $blah);
Note that i am using the i modifier for the regular expression. It matches case-insensitive, so that we do not need to specify a-z and A-Z.
been answered lots of times but:
function cleanit($input){
return preg_replace('/[^a-zA-Z0-9.]/s', '', $input);
}
$blah = cleanit("C$###.a534&");
you can use preg_replace
$text = preg_replace('/[' . preg_quote('CHARSYOUDONTWANT','/') . ']/','',$text);
on other case for only chars you want try this,
$text = preg_replace('/[^' . preg_quote('CHARSONLYYOUWANT','/') . ']/','',$text);
for example
$blah = "C$###.a534&";
$blah = preg_replace('/[' . preg_quote('$##&','/') . ']/','',$blah);
echo $blah;
Or do it the other way round:
$text = preg_replace('/[^a-zA-Z0-9.]/','',$text);
http://php.net/manual/en/function.preg-replace.php
replace all non-valid characters with the empty string.