3

I have a text file ("file.txt"):

5 (blah-blah) 001  
2 (blah) 006  

With a PHP code to find the first word, expression in parentheses, and last 3- or 4-digit numbers by searching for a pattern in line[number]:

<?php  
// file  
$file = file("file.txt");  

/* first line */
// match first word (number)  
preg_match("/^(\d+)/",$file[0],$first_word);  

// match expression within parentheses  
preg_match("/(?<=\().*(?=\))/s",$file[0],$within_par);  

// match last 3- & 4-digit numbers  
preg_match("/(\d{3,4})?(?!.*(\d{3,4}))/",$file[0],$last_word); 

/* repeats (second line) */  
preg_match("/^(\d+)/",$file[1],$first_word2);  
preg_match("/(?<=\().*(?=\))/s",$file[1],$within_par2);  
preg_match("/(\d{3,4})?(?!.*(\d{3,4}))/",$file[1],$last_word2); 
<?php

And an HTML code to display the matches line by line:

<div>
    <p><?php echo $first_word[0] ?></p>
    <p><?php echo $within_par[0] ?></p>
    <p><?php echo $last_word[0] ?></p>
</div>
<div>
    <p><?php echo $first_word2[0] ?></p>
    <p><?php echo $within_par2[0] ?></p>
    <p><?php echo $last_word2[0] ?></p>
</div>

But I would like to be able to display all the matches without having to list each one individually, both in my PHP code and HTML code. I would like to use preg_match_all to search in the text file, then foreach all matches, and echo/return each one, one div (with three patterns) at a time. (I have tried several different ways but I get an Array as a result.) What code can accomplish this?

2 Answers 2

0
<?php

$string = "5 (blah-blah) 001  
2 (blah) 006";

$result = preg_match_all("/(\d+)\s+\((.*?)\)\s+(\d+)/", $string, $matches);

if (count($matches) > 0) {
    unset($matches[0]);

    $sets = array();

    foreach ($matches as $key => $value) {
        foreach ($value as $key2 => $value2) {
            $sets[$key2][] = $value2;
        }
    }

    foreach ($sets as $key => $values) {
        echo '<div style="background-color: red;">';
        foreach ($values as $ind => $value) {
            echo '<p>'.$value.'</p>';
        }
        echo '</div>';
    }

    // Direct output (without an internal loop)
    foreach ($sets as $key => $values) {
        echo '<div style="background-color: orange;">';
        echo '<p>'.$values[0].'</p>';
        echo '<p>'.$values[1].'</p>';
        echo '<p>'.$values[2].'</p>';
        echo '</div>';
    }
}

?>

Now $sets will contain your values in the correct collection. I've added a foreach loop to print out the data as you want it.

Sign up to request clarification or add additional context in comments.

8 Comments

This is great! But I would like to echo each value separately, where it says: echo '<div>'; foreach ($values as $ind => $value) { echo '<p>'.$value.'</p>'; } echo '</div>'; So it would say something like: echo '<div>'; foreach ($values as $ind => $value) { echo '<p>'.$value1.'</p>'; echo '<p>'.$value2.'</p>'; echo '<p>'.$value3.'</p>'; } echo '</div>'; Where value1 is the first number, value2 the expression in parentheses, and value3 the last three numbers.
echo '<p>'.$values[0].'</p>'; where you can just use the INDEX keys [0] [1] [2] to access the different Array entries. I've updated the answer for you with an extra section to demo it.
How can I make this code work for preg_match_all("/(?<=\/).+/", $string, $matches), to find the text after the slash in a string, e.g. "/blah blah" ? Using preg_match works when I use foreach($matches as $match){ echo $match }, which outputs "blah blah". I would like to get all the matches like the above example, but preg_match_all does not work using the new pattern. Can you help me out?
What are you trying to achieve? The regex in my answer already strips the content between the ( ). It's better to maybe do string modification on those results, instead of "regex-ing" it even more, making it harder to decipher. I can add a little example in the answer if you can explain what you are trying to achieve. Actually this is a second question; next time don't hesitate to just make a new question from it in general. Long comment-chats isn't the way StackOverflow works :)
Like I said, instead of having 1 (blah) 001 and 2 (blah) 002, I have /blah , /blah blah , and I would like to use preg_match_all, with the regex /(?<=\/).+/ to capture the text after the slash and use your code to echo all the matches, but it does not seem to work with that regex.
|
0

You can extract your data using:

$matches = array();
preg_match_all("/([0-9]+) \(([a-zA-Z-]+)\) ([\d]+)/", $text, $matches);

example, on the text:

$text = "5 (blah-blah) 001 \n 6 (bloh-bloh) 002";

The result will be:

Array
(
    [0] => Array
        (
            [0] => 5 (blah-blah) 001
            [1] => 6 (bloh-bloh) 002
        )

    [1] => Array
        (
            [0] => 5
            [1] => 6
        )

    [2] => Array
        (
            [0] => blah-blah
            [1] => bloh-bloh
        )

    [3] => Array
        (
            [0] => 001
            [1] => 002
        )
)

So, if you read the content of the file with file_get_contents, you should be able to apply the preg_match_all and retrieve all your data.

1 Comment

Escaping ( and ) like that in PHP fails. I tried it too, but seems to trigger an error.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.