How to match a string line by line in php regex? - php

I have string with multiple newlines, each new line contains a new substring.
Here is an example of the string with 2 lines :
$x="Hello
World!
You can see Hello is in the first line and World! is in a newline.
Each substrings start and end with or without a newline(s)|space(s).
I want to match both lines.
My currunt code matched the second line and ignored the first.
if(preg_match_all("/^\n*\s*(Hello|World!)\s*$/i",$x,$m))
{print_r($m);}
Is there any way to fix this,so that both lines can be matched?

if(preg_match_all("/(Hello|World!)/i",$x,$m))
{
print_r($m);
}
If you user ^ $ it matches only the full line.
So the Hello part has no \n*\s* before Hello so it won't match.
If you change the script like above, it will only lookup for the words, reagless of having any stuff before or after the word.
Hope that helps.

Try this
$x="Hello
world! ";
preg_match_all("#\b(Hello|World!)\b#",$x,$m) ;
echo count($m)
Output
2
Phpfiddle Preview

I'm not sure what the "goal" is but this regex will match both lines. I changed your Hello|World to (.+?) as it matches any character and so would match variables if you are parsing code.
/^(.+?)[\n,\s,\t]{1,8}(.+?)$/
Here is your example with the new regex, so if I misinterpreted you can see what's going on.
<?php
$x="Hello
World!";
if(preg_match_all("/^(.+?)[\n,\s,\t]{1,8}(.+?)$/i",$x,$m))
{print_r($m);}
?>
you'll need to determine what and how many potential characters are between the first and second lines if your parsing more than a single series, and then modify the {1,8} to suit spaces, tabs, newlines, etc...

Related

laravel route with any character until next / [duplicate]

I am looking for a pattern that matches everything until the first occurrence of a specific character, say a ";" - a semicolon.
I wrote this:
/^(.*);/
But it actually matches everything (including the semicolon) until the last occurrence of a semicolon.
You need
/^[^;]*/
The [^;] is a character class, it matches everything but a semicolon.
^ (start of line anchor) is added to the beginning of the regex so only the first match on each line is captured. This may or may not be required, depending on whether possible subsequent matches are desired.
To cite the perlre manpage:
You can specify a character class, by enclosing a list of characters in [] , which will match any character from the list. If the first character after the "[" is "^", the class matches any character not in the list.
This should work in most regex dialects.
Would;
/^(.*?);/
work?
The ? is a lazy operator, so the regex grabs as little as possible before matching the ;.
/^[^;]*/
The [^;] says match anything except a semicolon. The square brackets are a set matching operator, it's essentially, match any character in this set of characters, the ^ at the start makes it an inverse match, so match anything not in this set.
None of the proposed answers did work for me. (e.g. in notepad++)
But
^.*?(?=\;)
did.
Try /[^;]*/
Google regex character classes for details.
sample text:
"this is a test sentence; to prove this regex; that is g;iven below"
If for example we have the sample text above, the regex /(.*?\;)/ will give you everything until the first occurence of semicolon (;), including the semicolon: "this is a test sentence;"
Try /[^;]*/
That's a negating character class.
This was very helpful for me as I was trying to figure out how to match all the characters in an xml tag including attributes. I was running into the "matches everything to the end" problem with:
/<simpleChoice.*>/
but was able to resolve the issue with:
/<simpleChoice[^>]*>/
after reading this post. Thanks all.
this is not a regex solution, but something simple enough for your problem description. Just split your string and get the first item from your array.
$str = "match everything until first ; blah ; blah end ";
$s = explode(";",$str,2);
print $s[0];
output
$ php test.php
match everything until first
This will match up to the first occurrence only in each string and will ignore subsequent occurrences.
/^([^;]*);*/
"/^([^\/]*)\/$/" worked for me, to get only top "folders" from an array like:
a/ <- this
a/b/
c/ <- this
c/d/
/d/e/
f/ <- this
Really kinda sad that no one has given you the correct answer....
In regex, ? makes it non greedy. By default regex will match as much as it can (greedy)
Simply add a ? and it will be non-greedy and match as little as possible!
Good luck, hope that helps.
This works for getting the content from the beginning of a line till the first word,
/^.*?([^\s]+)/gm
I faced a similar problem including all the characters until the first comma after the word entity_id. The solution that worked was this in Bigquery:
SELECT regexp_extract(line_items,r'entity_id*[^,]*')

regex to match string that only has one uppercase letter

I am curling an page and getting the output
however what is happening is that the html encoding is being removed so new lines are being skipped,
so it looks like this
This is Bob. He lives in an boatBut he only has one oar to row with.
in order to detect new lines I figure it was easier to just check for strings that only have One upper case letter and spaces inbetween, so far I have this
(\s\w+\s\w+.\s\D+[a-z][A-Z])
However this does not seem to work
as it only matches this
is Bob. He lives in an boatB
see here http://regex101.com/r/gH0lW1
how to match all strings that have spaces and match all strings up to one Uppercase letter
Update: this will split on the condition without losing any characters
<?php
$string = "This is Bob. He lives in an boatBut he only has one oar to row with.He also does stuff, it is cool.";
$array = preg_split('/(?<=[a-z.])(?=[A-Z])/', $string);
print_r($array);
?>
Use a positive lookbehind to ensure you capture a capital after a lowercase:
(?<=[a-z])[A-Z]
http://regex101.com/r/cB7bD8
You could use php's preg_split if you want, to explode the result on this regex.
(.*?(?:\w+(?=[A-Z]))|\1)
This regex has a recursive part that will match more than 1 sentence in a whole text. So you can check the Live demo and see the matched groups.
But,
If you wanna include a newline on each sentence begins after a period (.) as well, then I modify above regex to this:
(.*?(?:(?:\w+|\. *)(?=[A-Z]))|\1)
and now you can compare results with the first regex HERE

Using regex, replace any line within a block of text that starts with "embed:"

As the title says, I am looking for a regex, using php code, that given a $string with line breaks such as the following:
Hello my name is John Doe. Here is a cool video:
embed:http://youtube.com/watch......
I hope you liked it!
It would return:
Hello my name is John Doe. Here is a cool video:
I hope you liked it!
This should do it:
preg_replace('/^embed:.*\s*/m', '', $block_of_text);
Explanation:
The /m modifier enabled multi-line mode (so you can easily match line-based patterns)
It matches the start of the line using the caret symbol (anchor): ^
Matches the "embed: string
Matches until the end of the line using .*
Matches any newlines and white spaces after the current line (this cleans up the empty lines better)
Try this :
preg_replace('#embed:.*?\n*#m', '', $string);

Regex to strip some lines out of a text file

I need to try and strip out lines in a text file that match a pattern something like this:
anything SEARCHTEXT;anything;anything
where SEARCHTEXT will always be a static value and each line ends with a line break. Any chance someone could help with the regext for this please? Or give me some ideas on where to start (been to many years since I looked at regex).
I am planning on using PHP's preg_replace() for this.
Thanks.
This solution removes all lines in $text which contain the sub-string SEARCHTEXT:
$text = preg_replace('/^.*?SEARCHTEXT.*\n?/m', '', $text);
My benchmark tests indicate that this solution is more than 10 times faster than '/\n?.*SEARCHTEXT.*$/m' (and this one correctly handles the case where the first line matches and the second one doesn't).
Use a regex to match the whole line like so:
^.*SEARCHTEXT.*$
preg_replace would be a good option for this.
$str = preg_replace('/\n?.*SEARCHTEXT.*$/m', '', $str);
The \n escape matches the line break for the matched line. This way matched lines are removed and the replace method does not just leave empty lines in the string.
The /m flag makes the caret (^) match the start of each line instead of the start of the string.

Where did I go wrong in my regex lookaround?

I'm trying to pull the first paragraph out of Markdown formatted documents:
This is the first paragraph.
This is the second paragraph.
The answer here gives me a solution that matches the first string ending in a double line break.
Perfect, except some of the texts begin with Markdown-style headers:
### This is an h3 header.
This is the first paragraph.
So I need to:
Skip any line that begins with one or more # symbols.
Match the first string ending in a double line break.
In other words, return 'This is the first paragraph' in both of the examples above.
So far, I've tried many variations on:
"/(?s)(?:(?!\#))((?!(\r?\n){2}).)*+/
But I can't get it to return the proper match.
Where did I go wrong in my lookaround?
I'm doing this in PHP (preg_match()), if that makes a difference.
Thanks!
You could try
"/(?sm)^[^#](?:(?!(?:\r\n|\r|\n){2}).)*/"
I enable the multiline option by using (?sm) instead of (?s) and start each check at a new line, which may not be starting with a #. And I used \r\n|\r|\n instead of \r?\n because my testing environment had funny line breaks =)

Categories