Bibtex php preg_match_all

Tengo un archivo de texto con una exportación Bibtex. El archivo de texto tiene una serie de entradas que siguen el patrón siguiente.

@article{ls_leimeister,
  added-at = {2013-01-18T11:14:11.000+0100},
  author = {Wegener, R. and Leimeister, J. M.},
  biburl = {http://www.bibsonomy.org/bibtex/27bb26b4b4858439f81aa0ec777944ac5/ls_leimeister},
  journal = {International Journal of Technology Enhanced Learning (to appear)},
  keywords = {Challenges Communities: Factors Learning Success VirtualCommunity and itegpub pub_jml pub_rwe},
  note = {JML_390},
  title = {Virtual Learning Communities: Success Factors and Challenges},
  year = 2013
}

Quiero usar php y consideré preg_match_all

Lo siguiente no me llevó a ninguna parte:

preg_match_all('/@^.*}$/', file_get_contents($file_path),$results);

Quería comenzar simple, pero eso realmente no funcionó. Soy un poco nuevo en php RegEx.

El resultado final perfecto sería:

Array
    (
        [0] => Array
            (
                ['type'] => article
                ['unique_name'] => ls_leimeister
                ['added-at'] => 2013-01-18T11:14:11.000+0100
                ['author'] => Wegener, R. and Leimeister, J. M.
                ['biburl'] => http://www.bibsonomy.org/bibtex/27bb26b4b4858439f81aa0ec777944ac5/ls_leimeister
                ['journal'] => International Journal of Technology Enhanced Learning (to appear)
                ['keywords'] => Challenges Communities: Factors Learning Success VirtualCommunity and itegpub pub_jml pub_rwe
                ['note'] => JML_390
                ['title'] => Virtual Learning Communities: Success Factors and Challenges
                ['year'] => 2013
            )

        [1] => Array
            (
                [...] => …
            )

    )

preguntado el 28 de febrero de 13 a las 12:02

@renanbr renacer recomienda: renanbr/bibtex-parser github.com/renanbr/bibtex-parser (que supongo que es su propia invención). -

Toda la documentación de BibTex que he visto tendrá el valor del año entre llaves. ¿Es esto un error tipográfico al publicar? -

2 Respuestas

Prueba esto: aquí solo he obtenido type y unique_name, al mirarlo, puede obtener todos los demás.

$str = '@article{ls_leimeister,
  added-at = {2013-01-18T11:14:11.000+0100},
  author = {Wegener, R. and Leimeister, J. M.},
  biburl = {http://www.bibsonomy.org/bibtex/27bb26b4b4858439f81aa0ec777944ac5/ls_leimeister},
  journal = {International Journal of Technology Enhanced Learning (to appear)},
  keywords = {Challenges Communities: Factors Learning Success VirtualCommunity and itegpub pub_jml pub_rwe},
  note = {JML_390},
  title = {Virtual Learning Communities: Success Factors and Challenges},
  year = 2013
}';

preg_match_all('/@(?P<type>\w+){(?P<unique_name>\w+),(.*)/',$str,$matches);

echo $matches['type'][0];
echo "<br>";
echo $matches['unique_name'][0];
echo "<br>";

echo "<pre>";
print_r($matches);

El formato de matriz de salida será un poco diferente al suyo, pero puede cambiar este formato al suyo.

Respondido 28 Feb 13, 12:02

Gracias, esto funciona, pero las otras líneas son las más difíciles. El número de líneas es variable y también algunas líneas tienen '{ ... }' y otras no. - Espurio

Sí, sé que es difícil, pero intenta hacerlo. - Prasanth Bendra

preg_match_all('/@(\w+){(.+),\s+(\S+)\s+=\s+{(.*)},(.*)/',$file_content,$resultados); Esto produce la primera línea también. ¿Cómo puedo decirle a RegEx que recupere un número indefinido de líneas con el mismo formato? Tendría que leer las coincidencias de las entradas y luego hacer otro preg_match para las diferentes coincidencias. - Espurio

Necesito preg_match para todas las entradas primero y luego hacer el preg_match que publiqué anteriormente. preg_match_all('/@\w+{.+,\s+$([\s\S]+)}$/',$file_content,$resultados); preg_match_all('/@\w+{.+,\s+$(.*)}$/',$file_content,$resultados); Ninguno de los dos funciona, ¿alguna ayuda? - Espurio

@PrasanthBendra Gracias, con su código, es fácil hacer coincidir las palabras clave como title, author y así sucesivamente por:preg_match_all('/(?P<unique_name>\w+)\s=\s\{(.*?)\},/s',$str,$matches);, tenga en cuenta que /s significa multilínea, ver php.net/manual/en/reference.pcre.pattern.modifiers.php - van abel

Patrón: /^@([^{]+)\{([^,]+),\s*$|^\s*([^\R@=]+) = \{(.*?)}/ms (Demo)

Este patrón tiene dos alternativas; cada uno contiene dos grupos de captura.

  • type y unique_name son capturados y almacenados en elementos [1] y [2].
  • todos los demás pares clave-valor se almacenan en elementos [3] y [4].

Este almacenamiento de arreglo separado permite un procesamiento confiable cuando se construye la estructura de arreglo de salida deseada.

Entrada:

$bibtex='@BOOK{ko,
   title = {Wissenschaftlich schreiben leicht gemacht},
   publisher = {Haupt},
   year = {2011},
   author = {Kornmeier, M.},
   number = {3154},
   series = {UTB},
   address = {Bern},
   edition = {4},
   subtitle = {für Bachelor, Master und Dissertation}
}

@BOOK{nial,
   title = {Wissenschaftliche Arbeiten schreiben mit Word 2010},
   publisher = {Addison Wesley},
   year = {2011},
   author = {Nicol, N. and Albrecht, R.},
   address = {München},
   edition = {7}
}

@ARTICLE{shome,
   author = {Scholz, S. and Menzl, S.},
   title = {Alle Wege führen nach Rom},
   journal = {Medizin Produkte Journal},
   year = {2011},
   volume = {18},
   pages = {243-254},
   subtitle = {ein Vergleich der regulatorischen Anforderungen und Medizinprodukte
   in Europa und den USA},
   issue = {4}
}

@INBOOK{shu,
   author = {Schulz, C.},
   title = {Corporate Finance für den Mittelstand},
   booktitle = {Praxishandbuch Firmenkundengeschäft},
   year = {2010},
   editor = {Hilse, J. and Netzel, W and Simmert, D.B.},
   booksubtitle = {Geschäftsfelder Risikomanagement Marketing},
   publisher = {Gabler},
   pages = {97-107},
   location = {Wiesbaden}
}';

Método: (Demo)

$pattern='/^@([^{]+)\{([^,]+),\s*$|^\s*([^\R@=]+) = \{(.*?)}/ms';
if(preg_match_all($pattern,$bibtex,$out,PREG_SET_ORDER)){
    foreach($out as $line){
        if(isset($line[1])){
            if(!isset($line[3])){  // this is the starting line of a new set
                if(isset($temp)){
                    $result[]=$temp;  // send $temp data to permanent storage
                }
                $temp=['type'=>$line[1],'unique_name'=>$line[2]];  // declare fresh new $temp
            }else{
                $temp[$line[3]]=$line[4];  // continue to store the $temp data
            }
        }
    }
    $result[]=$temp;  // store the final $temp data
}
var_export($result);

Salida:

array (
  0 => 
  array (
    'type' => 'BOOK',
    'unique_name' => 'ko',
    'title' => 'Wissenschaftlich schreiben leicht gemacht',
    'publisher' => 'Haupt',
    'year' => '2011',
    'author' => 'Kornmeier, M.',
    'number' => '3154',
    'series' => 'UTB',
    'address' => 'Bern',
    'edition' => '4',
    'subtitle' => 'für Bachelor, Master und Dissertation',
  ),
  1 => 
  array (
    'type' => 'BOOK',
    'unique_name' => 'nial',
    'title' => 'Wissenschaftliche Arbeiten schreiben mit Word 2010',
    'publisher' => 'Addison Wesley',
    'year' => '2011',
    'author' => 'Nicol, N. and Albrecht, R.',
    'address' => 'München',
    'edition' => '7',
  ),
  2 => 
  array (
    'type' => 'ARTICLE',
    'unique_name' => 'shome',
    'author' => 'Scholz, S. and Menzl, S.',
    'title' => 'Alle Wege führen nach Rom',
    'journal' => 'Medizin Produkte Journal',
    'year' => '2011',
    'volume' => '18',
    'pages' => '243-254',
    'subtitle' => 'ein Vergleich der regulatorischen Anforderungen und Medizinprodukte
   in Europa und den USA',
    'issue' => '4',
  ),
  3 => 
  array (
    'type' => 'INBOOK',
    'unique_name' => 'shu',
    'author' => 'Schulz, C.',
    'title' => 'Corporate Finance für den Mittelstand',
    'booktitle' => 'Praxishandbuch Firmenkundengeschäft',
    'year' => '2010',
    'editor' => 'Hilse, J. and Netzel, W and Simmert, D.B.',
    'booksubtitle' => 'Geschäftsfelder Risikomanagement Marketing',
    'publisher' => 'Gabler',
    'pages' => '97-107',
    'location' => 'Wiesbaden',
  ),
)

Esta es el sitio de la que extraje nuevas cadenas de entrada de muestra.

Respondido el 12 de diciembre de 17 a las 14:12

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.