-1

I have the contents of a text file in a php string. Now I want to store the two characters which occur before the following strings - "(A)","(B)","(C)","(B+)" For example if the php variable contains something like -

33(F) 15352(1) 24 31 55(B+) 15360(1) 6 32 38 70(A) 2 3 4 5 6 7 8 9 10
10
*Passed with Grace Marks
*SID:  Student  ID;                          SchemeID:  The  scheme  
applicable  to  the  student.
Date on which pdf made: 09/10/2018
RTSID: 2018100901520151640002

Then I want to store 33,70 in an array. Note that I want to create a numeric array.

  • 1
    Can you please provide explanation? I don't understand how `33,70` is the desire output? shouldn't it be `55,70`? – dWinder Jan 27 '19 at 13:22
  • I was just giving example. Like every two characters before something like "(F)","(A)". So output will be 33,55,70 –  Jan 27 '19 at 13:26

2 Answers2

2

This is a much better answer than mine (by @Andreas):

    $re = '/(\d+)\(([A-Z]\+?)\)/m';
    $str = '33(F) 15352(1) 24 31 55(B+) 56(B+) 15360(1) 6 32 38 70(A) 2 3 4 5 6 7 8 9 10
    10
    *Passed with Grace Marks
    *SID:  Student  ID;                          SchemeID:  The  scheme  
    applicable  to  the  student.
    Date on which pdf made: 09/10/2018
    RTSID: 2018100901520151640002';


    preg_match_all($re, $str, $matches);
    $res = array_map(function($x, $y){
        return [$y, $x];
    },$matches[1], $matches[2]);
    print_r($res);

For one single input, this would work, and its not the best:

      function f(){
        $inputs = '33(F) 15352(1) 24 31 55(B+) 15360(1) 6 32 38 70(A) 2 3 4 5 6 7 8 9 10
        10
        *Passed with Grace Marks
        *SID:  Student  ID;                          SchemeID:  The  scheme  
        applicable  to  the  student.
        Date on which pdf made: 09/10/2018
        RTSID: 2018100901520151640002';

        $a=strpos($inputs,'(A)');
        $b=substr($inputs, $a-2,2);
        var_dump($b);
      }

    f();
Emma
  • 27,428
  • 11
  • 44
  • 69
  • 1
    In theory this method works, but as soon as it's 3 or 4 digit numbers it stops working. You could solve that by fist strpos the (A) then strrpos to the previous space. Between those two positions is the number. But with all that, a preg_match is far simpler. – Andreas Jan 27 '19 at 15:05
0

Another option is to using preg_match_all and capture 1+ digits \d+ (or 2 digits exactly \d{2} in a capturing group followed by matching an uppercase char followed by an optional plus sign \([A-Z]\+?

Then from the resulting array convert the values using array_map and intval.

For example:

$re = '/(\d+)\([A-Z]\+?\)/';
$str = '33(F) 15352(1) 24 31 55(B+) 15360(1) 6 32 38 70(A) 2 3 4 5 6 7 8 9 10
10
*Passed with Grace Marks
*SID:  Student  ID;                          SchemeID:  The  scheme  
applicable  to  the  student.
Date on which pdf made: 09/10/2018
RTSID: 2018100901520151640002';

preg_match_all($re, $str, $matches);
var_dump(array_map('intval',$matches[1]));

Result

array(3) {
  [0]=>
  int(33)
  [1]=>
  int(55)
  [2]=>
  int(70)
}

Php demo

The fourth bird
  • 154,723
  • 16
  • 55
  • 70
  • 1
    Perhaps more user-friendly is to have a input of what to find and output them with the "key" as: https://3v4l.org/vbFSU – Andreas Jan 27 '19 at 15:11
  • @Andreas Thank you for your comment, that is a nice suggestion. Taking possible duplicates into account I would opt for something like https://3v4l.org/HPpjV – The fourth bird Jan 27 '19 at 17:41
  • 1
    That works too. But making an associative multidimensional array is in my opinion even better as you can easily find what value the `B+` s are. – Andreas Jan 27 '19 at 17:47