2017-09-29 1 views
0

J'ai un &[u8] et j'ai besoin de vérifier s'il est conforme à un certain modèle. Il existe des exemples d'utilisation d'expressions régulières sur &[u8] dans le Regex documentation et dans the module documentation. Je pris le code de the examples section et de le mettre dans un main() et ajouté quelques déclarations:Comment utiliser l'expression rationnelle Rust sur des octets (Vec <u8> ou & [u8])?

extern crate regex; 
use regex::Regex; 

fn main() { 
    let re = Regex::new(r"'([^']+)'\s+\((\d{4})\)").unwrap(); 
    let text = b"Not my favorite movie: 'Citizen Kane' (1941)."; 
    let caps = re.captures(text).unwrap(); 
    assert_eq!(&caps[1], &b"Citizen Kane"[..]); 
    assert_eq!(&caps[2], &b"1941"[..]); 
    assert_eq!(&caps[0], &b"'Citizen Kane' (1941)"[..]); 
    // You can also access the groups by index using the Index notation. 
    // Note that this will panic on an invalid index. 
    assert_eq!(&caps[1], b"Citizen Kane"); 
    assert_eq!(&caps[2], b"1941"); 
    assert_eq!(&caps[0], b"'Citizen Kane' (1941)"); 
} 

Je ne comprends pas comment ce code exemple diffère de correspondance de chaîne régulière, et même le compilateur se plaint d'attendre un &str. En général, le code n'indique pas en quoi il diffère de la correspondance de chaîne habituelle, avec laquelle je n'ai aucun problème.

Je suppose que j'ai fait quelque chose de fondamentalement faux, comme une importation manquante ou plus précise. Je suis dans un jeu de devinettes ici, comme les docs ne parviennent pas à fournir des exemples de travail (comme ils le font régulièrement), et cette fois, le compilateur ne parvient pas à me pousser dans la bonne direction.

Voici les messages du compilateur:

error[E0308]: mismatched types 
--> src/main.rs:7:28 
    | 
7 |  let caps = re.captures(text).unwrap(); 
    |       ^^^^ expected str, found array of 45 elements 
    | 
    = note: expected type `&str` 
      found type `&[u8; 45]` 

error[E0277]: the trait bound `str: std::cmp::PartialEq<[u8]>` is not satisfied 
--> src/main.rs:8:5 
    | 
8 |  assert_eq!(&caps[1], &b"Citizen Kane"[..]); 
    |  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ can't compare `str` with `[u8]` 
    | 
    = help: the trait `std::cmp::PartialEq<[u8]>` is not implemented for `str` 
    = note: required because of the requirements on the impl of `std::cmp::PartialEq<&[u8]>` for `&str` 
    = note: this error originates in a macro outside of the current crate 

error[E0277]: the trait bound `str: std::cmp::PartialEq<[u8]>` is not satisfied 
--> src/main.rs:9:5 
    | 
9 |  assert_eq!(&caps[2], &b"1941"[..]); 
    |  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ can't compare `str` with `[u8]` 
    | 
    = help: the trait `std::cmp::PartialEq<[u8]>` is not implemented for `str` 
    = note: required because of the requirements on the impl of `std::cmp::PartialEq<&[u8]>` for `&str` 
    = note: this error originates in a macro outside of the current crate 

error[E0277]: the trait bound `str: std::cmp::PartialEq<[u8]>` is not satisfied 
    --> src/main.rs:10:5 
    | 
10 |  assert_eq!(&caps[0], &b"'Citizen Kane' (1941)"[..]); 
    |  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ can't compare `str` with `[u8]` 
    | 
    = help: the trait `std::cmp::PartialEq<[u8]>` is not implemented for `str` 
    = note: required because of the requirements on the impl of `std::cmp::PartialEq<&[u8]>` for `&str` 
    = note: this error originates in a macro outside of the current crate 

error[E0277]: the trait bound `str: std::cmp::PartialEq<[u8; 12]>` is not satisfied 
    --> src/main.rs:13:5 
    | 
13 |  assert_eq!(&caps[1], b"Citizen Kane"); 
    |  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ can't compare `str` with `[u8; 12]` 
    | 
    = help: the trait `std::cmp::PartialEq<[u8; 12]>` is not implemented for `str` 
    = note: required because of the requirements on the impl of `std::cmp::PartialEq<&[u8; 12]>` for `&str` 
    = note: this error originates in a macro outside of the current crate 

error[E0277]: the trait bound `str: std::cmp::PartialEq<[u8; 4]>` is not satisfied 
    --> src/main.rs:14:5 
    | 
14 |  assert_eq!(&caps[2], b"1941"); 
    |  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ can't compare `str` with `[u8; 4]` 
    | 
    = help: the trait `std::cmp::PartialEq<[u8; 4]>` is not implemented for `str` 
    = note: required because of the requirements on the impl of `std::cmp::PartialEq<&[u8; 4]>` for `&str` 
    = note: this error originates in a macro outside of the current crate 

error[E0277]: the trait bound `str: std::cmp::PartialEq<[u8; 21]>` is not satisfied 
    --> src/main.rs:15:5 
    | 
15 |  assert_eq!(&caps[0], b"'Citizen Kane' (1941)"); 
    |  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ can't compare `str` with `[u8; 21]` 
    | 
    = help: the trait `std::cmp::PartialEq<[u8; 21]>` is not implemented for `str` 
    = note: required because of the requirements on the impl of `std::cmp::PartialEq<&[u8; 21]>` for `&str` 
    = note: this error originates in a macro outside of the current crate 

Répondre

1

et a ajouté quelques déclarations

Malheureusement, vous avez ajouté les mauvaises. Notez comment la documentation que vous avez liée est pour la structure regex::bytes::Regex, pas regex::Regex - ils sont deux types différents!

extern crate regex; 
use regex::bytes::Regex; 
//   ^^^^^ 

fn main() { 
    let re = Regex::new(r"'([^']+)'\s+\((\d{4})\)").unwrap(); 
    let text = b"Not my favorite movie: 'Citizen Kane' (1941)."; 
    let caps = re.captures(text).unwrap(); 

    assert_eq!(&caps[1], &b"Citizen Kane"[..]); 
    assert_eq!(&caps[2], &b"1941"[..]); 
    assert_eq!(&caps[0], &b"'Citizen Kane' (1941)"[..]); 

    assert_eq!(&caps[1], b"Citizen Kane"); 
    assert_eq!(&caps[2], b"1941"); 
    assert_eq!(&caps[0], b"'Citizen Kane' (1941)"); 
} 

que les documents ne parviennent pas à fournir des exemples de travail (comme ils le font régulièrement)

Notez que les blocs de code dans la documentation sont compilés et exécutés par défaut, donc mon expérience est qu'il est assez rare que les exemples ne fonctionnent pas.

+0

Merci. C'est la première fois que je vois cette "importation imbriquée", je pensais que regex :: Regex importait tout dans ce module. J'utilise à la fois & [u8] et les chaînes de sorte que j'ai dû renommer la version u8 en utilisant "use regex :: bytes :: Regex comme Regex_u8;". – user103185

+1

@ user103185 'utiliser regex :: Regex' n'apporte que le type' regex :: Regex'. 'use regex :: *' apporterait tous les types/traits dans le module 'regex' (non récursivement). Vous pourriez aussi dire 'use regex :: bytes; bytes :: Regex :: new() ', etc. – Shepmaster

+0

Je crains que les docs, en tant que fonctionnalité principalement standard, omettent les clauses" extern "et" use ", donc ils ne compilent pas. Suggérer qu'un exemple fonctionne parce que tous les exemples sont compilés et vérifiés (comme je le savais déjà) aide à confondre les débutants encore plus. Comme les modules et les importations sont essentiels à l'utilisation de Rust, il serait très bénéfique que chaque échantillon comprenne ces clauses, pour la pratique quotidienne. Mais quand ce n'est pas le cas, au moins un lien vers une page, montrant comment compiler et exécuter un exemple, serait très apprécié. Une fois un gain merci de clarifier l'importation. – user103185