I'd like to return string between two characters, # and dot (.).
I tried to use regex but cannot find it working.
(#(.*?).)
Anybody?
Your regular expression almost works, you just forgot to escape the period. Also, in PHP you need delimiters:
'/#(.*?)\./s'
The s is the DOTALL modifier.
Here's a complete example of how you could use it in PHP:
$s = 'foo#bar.baz';
$matches = array();
$t = preg_match('/#(.*?)\./s', $s, $matches);
print_r($matches[1]);
Output:
bar
Try this regular expression:
#([^.]*)\.
The expression [^.]* will match any number of any character other than the dot. And the plain dot needs to be escaped as it’s a special character.
this is the best and fast to use
function get_string_between ($str,$from,$to) {
$string = substr($str, strpos($str, $from) + strlen($from));
if (strstr ($string,$to,TRUE) != FALSE) {
$string = strstr ($string,$to,TRUE);
}
return $string;
}
If you're learning regex, you may want to analyse those too:
#\K[^.]++(?=\.)
(?<=#)[^.]++(?=\.)
Both these regular expressions use possessive quantifiers (++). Use them whenever you can, to prevent needless backtracking. Also, by using lookaround constructions (or \K), we can match the part between the # and the . in $matches[0].
Related
This is the code:
<?php
$pattern =' abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890';
$text = "kdaiuyq7e611422^^$^vbnvcn^vznbsjhf";
$text_split = str_split($text,1);
$data = '';
foreach($text_split as $value){
if (preg_match("/".$value."/", $pattern )){
$data = $data.$value;
}
if (!preg_match('/'.$value.'/', $pattern )){
break;
}
}
echo $data;
?>
Current output:
kdaiuyq7e611422^^$^vbnvcn^vznbsjhf
Expected output:
kdaiuyq7e611422
Please help me editing my code error. In pattern there is no ^ or $. But preg_match is showing matched which is doubtful.
You string $text have ^ which will match the begin of the string $pattern.
So the preg_match('/^/', $pattern) will return true, then the ^ will append to $data.
You should escape the ^ as a raw char, not a special char with preg_match('/\^/', $pattern) by the help of preg_quote() which will escape the special char.
There is no need to split your string up like that, the whole point of a regular expression is you can specify all the conditions within the expression. You can condense your entire code down to this:
$pattern = '/^[[:word:] ]+/';
$text = 'kdaiuyq7e611422^^$^vbnvcn^vznbsjhf';
preg_match($pattern, $text, $matches);
echo $matches[0];
Kris has accurately isolated that escaping in your method is the monkey wrench. This can be solved with preg_quote() or wrapping pattern characters in \Q ... \E (force characters to be interpreted literally).
Slapping that bandaid on your method (as you have done while answering your own question) doesn't help you to see what you should be doing.
I recommend that you do away with the character mask, the str_split(), and the looped calls of preg_match(). Your task can be accomplished far more briefly/efficiently/directly with a single preg_match() call. Here is the clean way that obeys your character mask fully:
Code: (Demo)
$text = "kdaiuyq7e611422^^$^vbnvcn^vznbsjhf";
echo preg_match('/^[a-z\d ]+/i',$text,$out)?$out[0]:'No Match';
Output:
kdaiuyq7e611422
miknik's method was close to this, but it did not maintain 100% accuracy given your question requirements. I'll explain:
[:word:] is a POSIX Character Class (functioning like \w) that represents letters(uppercase and lowercase), numbers, and an underscore. Unfortunately for miknik, the underscore is not in your list of wanted characters, so this renders the pattern slightly inaccurate and may be untrustworthy for your project.
i need to explode youtube url from this line:
[embed]https://www.youtube.com/watch?v=L3HQMbQAWRc[/embed]
It is possible? I need to delete [embed] & [/embed].
preg_match is what you need.
<?php
$str = "[embed]https://www.youtube.com/watch?v=L3HQMbQAWRc[/embed]";
preg_match("/\[embed\](.*)\[\/embed\]/", $str, $matches);
echo $matches[1]; //https://www.youtube.com/watch?v=L3HQMbQAWRc
$string = '[embed]https://www.youtube.com/watch?v=L3HQMbQAWRc[/embed]';
$string = str_replace(['[embed]', '[/embed]'], '', $string);
See str_replace
why not use str_replace? :) Quick & Easy
http://php.net/manual/de/function.str-replace.php
Just for good measure, you can also use positive lookbehind's and lookahead's in your regular expressions:
(?<=\[embed\])(.*)(?=\[\/embed\])
You'd use it like this:
$string = "[embed]https://www.youtube.com/watch?v=L3HQMbQAWRc[/embed]";
$pattern = '/(?<=\[embed\])(.*)(?=\[\/embed\])/';
preg_match($pattern, $string, $matches);
echo $match[1];
Here is an explanation of the regex:
(?<=\[embed\]) is a Positive Lookbehind - matches something that follows something else.
(.*) is a Capturing Group - . matches any character (except a newline) with the Quantifier: * which provides matches between zero and unlimited times, as many times as possible. This is what is matched between the groups prior to and after. This are the droids you're looking for.
(?=\[\/embed\]) is a Positive Lookahead - matches things that come before it.
I may be pushing the boundaries of Regular Expressions, but who knows...
I'm working in php.
In something like:
preg_replace('/(?:\n|^)(={3,6})([^=]+)(\1)/','<h#>$2</h#>', $input);
Is there a way to figure out how many '=' (={3,6}) matched, so I can backreference it where the '#'s are?
Effectively turning:
===Heading 3=== into <h3>Heading 3</h3>
====Heading 4==== into <h4>Heading 4</h4>
...
You can use:
preg_replace('/(?:\n|^)(={3,6})([^=]+)(\1)/e',
"'<h'.strlen('$1').'>'.'$2'.'</h'.strlen('$1').'>'", $input);
Ideone Link
No, PCRE can't do that. You should instead use preg_replace_callback and do some character counting then:
preg_replace_callback('/(?:\n|^)(={3,6})([^=]+)(\1)/', 'cb_headline', $input);
function cb_headline($m) {
list(, $markup, $text) = $m;
$n = strlen($markup);
return "<h$n>$text</h$n>";
}
Additionally you might want to be forgiving with the trailing === signs. Don't use a backreference but allow a variable number.
You might also wish to use the /m flag for your regex, so you can keep ^ in place of the more complex (?:\n|^) assertion.
It is very simple with modifier e in regexp, no need in preg_replace_callback
$str = '===Heading 3===';
echo preg_replace('/(?:\n|^)(={3,6})([^=]+)(\1)/e',
'implode("", array("<h", strlen("$1"), ">$2</h", strlen("$1"), ">"));',
$str);
or this way
echo preg_replace('/(?:\n|^)(={3,6})([^=]+)(\1)/e',
'"<h".strlen("$1").">$2</h".strlen("$1").">"',
$str);
I would do it like this:
<?php
$input = '===Heading 3===';
$h_tag = preg_replace_callback('#(?:\n|^)(={3,6})([^=]+)(\1)#', 'paragraph_replace', $input);
var_dump($h_tag);
function paragraph_replace($matches) {
$length = strlen($matches[1]);
return "<h{$length}>". $matches[2] . "</h{$length}>";
}
?>
Output:
string(18) "<h3>Heading 3</h3>"
I have this code:
$string = "123456ABcd9999";
$answer = ereg("([0-9]*)", $string, $digits);
echo $digits[0];
This outputs '123456'. I'd like it to output '1234569999' ie. all the digits. How can I achieve this. I've been trying lots of different regex things but can't figure it out.
First, don't use ereg (it's deprecated). Secondly, why not replace it out:
$answer = preg_replace('#\D#', '', $string);
Note that \D is the inverse of \d. So \d matches all decimal numeric characters (0-9), therefore \D matches anything that \d does not match...
You could use preg_replace for this, preg_replace("/[^0-9]/", "", $string) for example.
I'm trying to use regular expressions (preg_match and preg_replace) to do the following:
Find a string like this:
{%title=append me to the title%}
Then extract out the title part and the append me to the title part. Which I can then use to perform a str_replace(), etc.
Given that I'm terrible at regular expressions, my code is failing...
preg_match('/\{\%title\=(\w+.)\%\}/', $string, $matches);
What pattern do I need? :/
I think it's because the \w operator doesn't match spaces. Because everything after the equal sign is required to fit in before your closing %, it all has to match whatever is inside those brackets (or else the entire expression fails to match).
This bit of code worked for me:
$str = '{%title=append me to the title%}';
preg_match('/{%title=([\w ]+)%}/', $str, $matches);
print_r($matches);
//gives:
//Array ([0] => {%title=append me to the title%} [1] => append me to the title )
Note that the use of the + (one or more) means that an empty expression, ie. {%title=%} won't match. Depending on what you expect for white space, you might want to use the \s after the \w character class instead of an actual space character. \s will match tabs, newlines, etc.
You can try:
$str = '{%title=append me to the title%}';
// capture the thing between % and = as title
// and between = and % as the other part.
if(preg_match('#{%(\w+)\s*=\s*(.*?)%}#',$str,$matches)) {
$title = $matches[1]; // extract the title.
$append = $matches[2]; // extract the appending part.
}
// find these.
$find = array("/$append/","/$title/");
// replace the found things with these.
$replace = array('IS GOOD','TITLE');
// use preg_replace for replacement.
$str = preg_replace($find,$replace,$str);
var_dump($str);
Output:
string(17) "{%TITLE=IS GOOD%}"
Note:
In your regex: /\{\%title\=(\w+.)\%\}/
There is no need to escape % as its
not a meta char.
There is no need to escape { and }.
These are meta char but only when
used as a quantifier in the form of
{min,max} or {,max} or {min,}
or {num}. So in your case they are treated literally.
Try this:
preg_match('/(title)\=(.*?)([%}])/s', $string, $matches);
The match[1] has your title and match[2] has the other part.