DAQ Tutorial, French only.

Ce document fait partie d’une série de tutoriels sur l’acquisition de données et le contrôles d’appareils. La partie 1 est disponible ici. Le présent document se retrouve à la fois dans le repo public d’enseignement de dccote et sur le site Web de DCC Lab. Le format Markdown est celui supporté par Typora.io. Une version PDF est disponible.


Le monde numérique

La question la plus simple se répond par oui ou par non. De la même façpn, la tâche la plus simple que l’on peut faire avec un appareil d’acquisition ou de contrôle est de lui faire dire oui ou non. Il y a plusieurs questions qui demandent des réponses binaires exclusives: vrai ou faux, 1 ou 0, “Je suis prêt” ou “Je ne suis pas prêt”, etc…

Les pionniers de l’informatique ont dû concevoir un système qui permettrait de représenter les valeurs sans ambiguïtés pour les stocker et les manipuler avec un circuit logique. Pour bien des raisons qui viennent à la fois de l’ingéniosité (il fallait y penser) et de l’opportunité technologique (le transistor semionducteur et son potentiel de fabrication et miniaturisation), il est devenu apparent qu’un système basé sur une représentation binaire des nombres et de leur transformation par des circuits logiques serait idéal. Les premiers circuits électroniques de type TTL (ou Transistor-Transistor-Logic) dans les années 60 sont devenus les premiers circuits logiques, c’est-à-dire des circuits traitant des données d’entrée en représentation binaire pour produire de l’information à la sortie, aussi sous forme binaire. L’ensemble des circuits logiques permet d’implémenter toutes les opérations nécessaires à un calcul. Nous reviendrons plus tard au très passionnant côté hardware de la naissance de l’informatique, mais pour l’instant il suffira de savoir que la représentation réelle des nombres et des instructions dans les chips est sous forme binaire: une tension est à 5V est VRAI (ou 1) et une tension à 0V est FAUX (ou 0)1.

Bits et octets

Un bit a 2 valeurs possibles, 0 ou 1. C’est la plus petite quantité d’information que nous puissions avoir sur quelque chose2. Une collection ordonnée de 8 bits est un octet. Chaque bit pouvant avoir deux valeurs, un octet peut donc avoir $2\times2\times2\times2\times2\times2\times2\times2=2^8 = 256$ valeurs différentes. Par commodité, nous représentons cela sous forme de nombre en base 2 (binaire). La séquence suivante de 8 bits 0 0 1 0 0 1 0 1 peut être prise pour avoir une valeur de:

0 ⨉ 2^7 + 0 ⨉ 2^6 + 1 ⨉ 2^5 + 0 ⨉ 2^4 + 0 ⨉ 2^3 + 1 ⨉ 2^2 + 0 ⨉ 2^1 + 1 ⨉ 2^0 = 37 dec.

Comprenons bien que l’interprétation d’un octet en nombre entier allant de 0 à 255 n’est rien de plus qu’une interprétation: on pourrait aussi interpréter ce nom autrement. Par exemple, on pourrait déterminer que si le dernier bit est 1, une sortie est activée par exemple.

Dans de nombreux textes, une valeur binaire est notée %00100101 (Python: 0b00100101) pour la différencier de la valeur décimale 100101, qui a pour valeur «cent mille cent un». Cependant, la notation binaire n’est pas pratique: elle prend beaucoup de place lorsqu’elle est écrite et il est difficile d’évaluer rapidement une valeur pour le non-expert. Par conséquent, une notation raccourci est l’hexadécimale ou la notation en base 16. Les “chiffres” hexadécimaux sont {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F}. Le nombre ci-dessus peut donc être ré-écrit sous la forme %10100101 = 10 ⨉ 16^1 + 5 ⨉ 16^0 ou 0xA5 en hexadécimal, le préfixe 0x (souvent seulement x) désignant hexadécimal. Évidemment, puisque la base 16 = 2^4on voit que la notation hexadécimale permet de regrouper les bits par groupe de 4: les moins significatifs (à droite) sont représentés par le chiffre 5 = %0101​ et les plus significatifs (à gauche) sont représentés par la lettre 0xA = %1010.

L’importance de la notation binaire vient du fait que tout langage de programmation que l’on utilisera pour communiquer avec notre appareil devra invariablement passer par des représentations en binaires et des octets, puisque c’est la représentation interne naturelle de l’ordinateur.

Exercices

    1. Écrivez la valeur suivante en binaire, décimal et hexadécimal:
      a. 12
      b. 0x45
      c. %1001101
      d. 230
      e. 0xF3
    2. Effectuez les opérations suivantes:
      a. % 00101101 +% 00100001
      b. 0xF6 – 0x41
      c. 0x29 – 0x56
    3. Multipliez %00111001 par 2, 4 et 8 et écrivez les réponses en binaire.
    4. Divisez %00111001 par 2 et écrivez la réponse en binaire.
    5. Multipliez 0xF3 par 16.

Premier branchement

Le plan ici est d’obtenir un système pour expérimenter. Il y aura bien sûr des moments où l’on pourra se questionner sur le fonctionnement exact d’un ou l’autre aspect. Cependant, pour l’instant, il s’agit simplement de mettre en place un “banc d’expérimentation” pour aider à la compréhension, pour démystifier certains aspects et pour permettre l’exploration. Ainsi, on utilise le module de communication UM232R de FTDI (specifications) de type UART. Ce module est très intéressant pour plusieurs raisons:

    1. Il se branche simplement dans le port USB de n’importe quel ordinateur
    2. Il ne demande aucun branchement supplémentaire pour être au moins fonctionnel
    3. Il permet de construire un systeme pour communiquer avec d’autres appareils. En fait, il permet de mettre à jour les vieux systèmes RS232 pour USB.
    4. Les drivers (pilotes en français) de FTDI existent pour toutes les plateformes
    5. Les puces USB de FTDI sont utilisées dans un très grand nombre d’appareils
    6. Les librairies de FTDI sont disponibles, simples et sans bugs, et sont supportées par Python.

Pour commencer, il faut se procurer le fameux module UM232R. La façon la plus simple, venez me voir à mon bureau POP-2141 et demandez-le moi, j’en ai quelques uns. Sinon, on peut les commander pour 28$ chez Digi-Key , numéro de pièce Digi-Key 768-1019-ND, ou FTDI UM232R. Idéalement, un petit kit de breadboard comme le 438-1047-ND serait acheté en même temps, mais n’importe quel breadboard fait l’affaire. On remarque:

    1. Il y a 24 lignes (ou pins en anglais), on commence a compter en haut à gauche en tournant dans le sens trigonométrique.
    2. Plusieurs lignes sont identifiées RST, GND, VCC, VIO mais d’autres sont identifiées avec des termes génériques DB0, DB1, etc…
    3. Le manuel indique qu’il y a une ligne nommée TXD (transmission data) et une nommée RXD (receiving data)
    4. Il y a une ligne RESET. Le manuel indique clairement que mettre cette ligne à 0V forcera un “reset” de la puce.
    5. Il y a deux lignes configurées par défaut CB0 et CB1 pour servir d’indicateurs de transmission et de réception avec une DEL.
    6. Un groupe de lignes est identifié comme faisant du hardware handshake: DTR, RTS, DSR, DTS
    7. Bien que nous soyions en 2018, il reste des lignes identifiées comme: Ring Indicator (RI, ligne 6) Data Carrier Detect Control Input (DCDC, ligne de tonalité d’un modem)

 

 

Pour l’instant, mes instructions seront pour macOS/Linux car c’est ce que j’utilise. D’autres instructions devraient suivre pour les autres plateformes, même si la tâche me donne plutôt le goût d’aller chez le dentiste me faire enlever la totalité des dents d’en bas. Sans anesthésie.

Expérience 1: brancher

Si vous branchez un câble USB dans le module, la magie du standard USB3 devrait faire son oeuvre si le driver FTDI est installé (souvent standard, sinon obtenez et installez-le). Votre “puce” apparaîtra comme un port série ou Virtual Comm Port (VCP). Les systèmes qui utilisent le standard POSIX (macOS4 et Linux) le montreront dans /dev/:

Nestor:anaconda2 dccote$ ls -l /dev/*usbserial*
crw-rw-rw-  1 root  wheel   18,  51 14 Oct 22:42 /dev/cu.usbserial-FTCBGW24
crw-rw-rw-  1 root  wheel   18,  50 14 Oct 22:42 /dev/tty.usbserial-FTCBGW24
Nestor:anaconda2 dccote$

Le port série en POSIX apparait en deux formes pour des raisons historiques: cu (callout) et tty (teletype). Nous prendrons cu* pour la communication avec les appareils. Le nom du port série (ici cu.usbserial-FTCBGW24 est programmé par FTDI directement dans la puce à la fabrication). La valeur FTCBGW24 est un numéro de série unique à chaque puce, donc la vôtre sera différente de la mienne.

Expérience 2: débrancher

Si on débranche le câble USB, le port de communication associé au module disparaitra du système car le module n’est plus disponible. On peut faire la même chose à l’aide d’un fil en connectant la ligne RST au GND pour forcer un reset du module. Lorsqu’on le fait, on voit:

Nestor:anaconda2 dccote$ ls -l /dev/*usbserial*
ls: /dev/*FT*: No such file or directory
Nestor:anaconda2 dccote$

Avant de continuer, on enlève la connexion entre RST et GND .

Expérience 3: parler

Le langage de référence dans ces tutoriels est Python, non pas pour sa puissance, sa convivialité ou l’élégance de sa syntaxe mais bien pour son universalité. La façon la plus rapide d’être opérationnel est de télécharger Anaconda2. Vous aurez un environnement et la majorité des modules importants pour travailler, incluant un petit module appelé libftdi. Surprenamment, les routines de port serie PySerial n’y sont pas, on les installe avec: easy_install PySerial. Par la suite, les programmes Python qui suivent peuvent être exécuter.

Le UM232R est une puce pour la communication série de type UART (Universal Asynchronous Receiver-Transmitter), c’est à dire qu’elle sert à transférer l’information vers un récepteur un bit à la fois. Pour l’instant, ignorons les détails et concentrons-nous sur la ligne de transmission TXD (ou DB0). Dans Python, on peut ouvrir la communication avec cette puce UM232R par “le port série”. En effet, tout ce que l’on écrit sera sur la ligne de transmission TXD et tout ce qui est sur la ligne RXD nous pourrons lire par le port série.

import serial
import time

text = 'a'
path = '/dev/cu.usbserial-FTCBGW24'
try:
    port = serial.Serial(path, 9600)
    bytesWritten = port.write(text)
    if bytesWritten == len(text):
        print('Wrote to port: %s' % port.name)
    else:
        print('Error when writing to port: %s' % port.name)

    time.sleep(.1)
    port.close()
except IOError:
    print('Unable to open the port with path: %s' % path)
except:
    print('Unknown error')

Pour commencer, idéalement, on utilise un oscilloscope. Ne vous en faites pas, l’expérience suivante ne nécessite pas d’oscilloscope.

En exécutant le code précédent (python parler.py) avec une sonde d’oscilloscope sur la ligne TXD/DB0 (la premiere ligne en haut à gauche), on verra la ligne osciller entre 0V et 5V, comme sur l’image suivante. La ligne est d’abord à 5V, ensuite descend à 0 pour environ 100 µs, remonte à 5V, redescend pendant 400 µs, remonte pour 200 µs et finalement descend 100 µs et remonte pour rester à 5 V.

 

Nous verrons les details de cette communication UART plus tard, mais on remarque:

    1. environ 100 µs est en fait précisément 104 µs, c’est-à-dire 1/9600 de secondes,
    2. la lettre ‘a’ est codée comme le code ASCII 97. En binaire, 97 s’écrit %10000110,
    3. à partir de la première descente, il y a 9 périodes de 104 µs pour un total de 936 µs sur l’écran d’oscilloscope. Si on remplace les période de 104 µs à 5V par 1 et celle de 104 µs à 0V par zéro, on obtient 0 suivi de 10000110.

On comprendra donc que la communication envoie la lettre ‘a’ (code 97) à 9600 bits per seconde. Dans le cas de la puce ici présente qui implémente le protocole UART, la ligne commence toujours à 5V pour commencer, descend à 0 le temps d’un “coup d’horloge”, et ensuite écrit la valeur en binaire:

Rien n’est connecté, donc notre module “parle dans le vide”. On vient de dire au module d’envoyer un “a” sur “ses lignes de sortie” mais cette information n’a pas été utilisée ou capté par personne, sauf notre oscilloscope.

Expérience 4: parler et illuminer

Ce n’est pas tout le monde qui a un oscilloscope. Pour visualiser un peu ce qui se passe, on peut utiliser une diode électroluminescente (DEL) et la connecter directement sur la ligne de transmission avec une résistance de 220 Ohms au ground. Pour bien voir ce qui se passe, on écrit plusieurs 0 en ligne, à la vitesse la plus lente permise (300 bits par seconde). Ainsi, la ligne TXD sera à 5V pour commencer, et descendra à 0 pour 30 ms, remontera brièvement à 5V pour descendre tout de suite, et ce 15 fois en ligne. La DEL sera allumée, ensuite essentiellement éteinte pendant 0.5 seconde (avec un minuscule petit flash de 3 ms à chaque 30 ms) et ensuite rallumée. Voir le video.

import serial
import time

data = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] 
path = '/dev/cu.usbserial-FTCBGW24'
try:
    port = serial.Serial(path, 300)
    bytesWritten = port.write(data)
    if bytesWritten == len(data):
        print('Wrote to port: %s' % port.name)
    else:
        print('Error when writing to port: %s' % port.name)

    time.sleep(1)
    port.close()
except IOError:
    print('Unable to open the port with path: %s' % path)
except:
    print('Unknown error')

Expérience 5: écouter dans le vide

Si on essaie de lire le module, on n’obtiendra rien: la ligne read() ne complètera jamais (il n’y a pas de timeout, il est infini par défaut):

import serial

path = '/dev/cu.usbserial-FTCBGW24'
try:
    port = serial.Serial(path)
    text = port.read() ## Bloquera ici. Faites Ctrl-C pour quitter.
    port.close()
except IOError:
    print('Unable to open the port with path: %s' % path)
except:
    print('Unknown error')

En effet, le module n’est aucunement connecté à quoi que ce soit pour lire des données. Il peut transmettre, mais n’a rien à lire.

Expérience 6: écouter l’écho

On peut par contre prendre le module et le connecter pour qu’il s’écoute lui-même. En effet, on connecte la ligne de sortie (TXD) à la ligne d’entrée (RXD). Ainsi, en excéutant le code suivant, on pourra écrire “hello” et lire “hello” par la suite.

import serial

text = 'hello'
path = '/dev/cu.usbserial-FTCBGW24'
try:
    port = serial.Serial(path)
    bytesWritten = port.write(text)

    if bytesWritten == len(text):
        print('Wrote to port: %s' % port.name)
    else:
        print('Error when writing to port: %s' % port.name)

    echo = port.read(bytesWritten)

    if bytesWritten == len(echo):
        print('Read from port: %s' % port.name)
    else:
        print('Error when reading to port: %s' % port.name)

    port.close()
except IOError:
    print('Unable to open the port with path: %s' % path)
except:
    print('Unknown error')

On appelle ce mode le mode ECHO, puisque tout ce qui est écrit sur le port est lu sur le même port. En exécutant le code précédent, on obtient “hello” en lecture après avoir écrit “hello” sur le port série. Le mode ECHO permet de tester notre compréhension de plusieurs façons car nous savons toujours ce qui devrait être lu sur le port: il s’agira de ce que l’on vient d’écrire.

1 En fait, le standard TTL demande une tension supérieure à 2V pour être considéré comme un logique VRAI et moins de 0.8V pour un logique FAUX.
2 Bien qu’il soit omniprésent en informatique, le terme «bit» a été inventé par Claude Shannon, père de la théorie de l’information.
3 Le standard USB est un standard complexe qui n’est pas nécessaire de comprendre pour l’instant. Cependant, un bon ingénieur devra comprendre la reconnaissance des appareils, l’association des drivers, les classes, les vendor ID, product ID, la sérialisation des ports, les endpoints, etc… Bien sur, nous verrons tout cela plus loin lorsque ce sera nécessaire.
4 Apple fournit depuis macOS 10 un driver FTDI avec le système, mais celui-ci n’est pas directement de FTDI mais bien d’Apple. On peut tout de même installer le driver de FTDI. Cependant, depuis macOS 10, qui resserre la sécurité, le driver doit obtenir la permission de l’Administrateur pour pouvoir s’executer.

Tutorial: Introduction to Control (French only)

I google Translated the original French article, which I use for teaching. I did not proofread this:

Over the years, I have developed a taste for the programming of “physical devices”. I like to control things that interact with the outside world: a microscope stage, a laser, an acquisition board, a camera, a printer, and so on. This taste has been transformed into expertise over the years, and several students come to see me (in my group, at Bliq and in the laboratory of information) with the taste to know more. It’s not always easy to transfer that knowledge, and that’s partly because of how I acquired it.

Indeed, my first contacts with the * hardware * came in the [Commodore-64] (https://en.wikipedia.org/wiki/Commodore_64) in 1983: the purchase of the computer at [Distribution to the Consumer ] (https://en.wikipedia.org/wiki/Distribution_to_consumers) was fine, but the subsequent purchase of a printer [Star NX-1000] (http://www.computerhistory.org/collections/catalog / 102645920) had suddenly multiplied the power of our machine, which otherwise only made drawings and * beeps * without really leaving any traces or change anything in the world around me. If we sent the right orders to the printer, she moved, she wrote, she drew. One day I was forced to pull out a screwdriver because the [joystick] (https://www.s-config.com/repairing-wico-retro-gaming-joysticks/) kept crashing because that we always played at the Olympics (jumping with obstacles asked to move the joystick from left to right without stopping as quickly as possible). I wanted to play, I did not have a joystick anymore because my sister was beating it too hard, I repaired it. Later, many of my friends and I learned to use the “[Copy-21-seconds]” (http://www.c64copyprotection.com/21-second-backup/), which was a hardware modification of the floppy disk that overrode the protection by sending the information read directly to the computer instead of letting the reader process it and block it. I had wires running past my disk drive. I did not understand anything about it, except that I could copy all the games I wanted. It was just as powerful as it was mysterious. I learned the assembly language on the C-64, partly thanks to an obscure book that my mother’s computer friend at the City of Quebec lent me, I discussed different things with other guys 12 years on the * BBS * of Quebec (the ancestor of the Internet), and I spent my evenings programming anything, no matter how: it was all wrong, but it was exciting. In the end, though, it worked. I was tripping.

When I started my PhD in physics at the University of Toronto in 1995, there was a course called * Microprocessor Interfacing Techniques *, given by the very experienced and passionate Jim Drummond. The goal was to show us how to interface the outside world with our computers. A dream class: we had the lectures filled with anecdotes of Prof. Drummond, then the laboratory filled with parts, chips, breadboards, 8088 Turbo PCs (nothing less) and acquisition cards. In addition, we had the * key * of the local to come at any time of day and night. So I finally learned about TTL logic, flip-flops, synchronous and asynchronous counters, scanning, analog output, how to read chip specification sheets, etc. The many bits of information gleaned left and right over the years ended up converging in a coherent whole: I managed to understand the smallest tiny details of a logical circuit while being able to make a sufficient abstraction into functional blocks to finally build a complete system.

With the benefit of 30 years of tapping computers, circuitry, firing fuses, breaking acquisition cards, skipping detectors, fixing * stepper motors * * drivers to graduate, or spending whole evening just to make to light an LED in a basic circuit, I realize that students who come to see me have not often had the chance * to experiment *. This is partly because computers are becoming more complicated, and several layers of complexity have been added for years: the processors are running parallel operations, the famous RS-232 printer or modem port has been replaced by the * Universal Serial Bus * port, and the operating systems, the memory protection, the preemptive multitasking, the security make that today, there is rarely a “memory box” that corresponds to pins on the back of the computer (this [that the C-64 had] (https://www.c64-wiki.com/wiki/User_Port)), and the exact order of the execution of the operations n ‘ is not always known (easily controlled with sys 49152 for example on the C-64, the prediction memory box for games). Thus, experimenting as a novice becomes more and more difficult because the walk is much higher than in 1983 when I started.

So I hope, with a series of small tutorials, to make a basic introduction to Device Control. This will obviously start with extremely simple tutorials for the initiated but which should allow you to acquire the knowledge to do the Control of Devices through a methodical experiment based on experimentation.

In the next article, we will begin with the very simple construction of a tiny chip-based circuit of FTDI DLP-USB245M to get, as simply as possible, access to * digital pins * output and Entrance.

(Français) Les expressions régulières

# Tutoriel

Les expressions régulières

Les expressions régulières permettent de reconnaître des patrons dans du texte et d’en extraire l’information. D’une curiosité de programmeur qui a pris racine avec awk et sed, mais surtout le langage Perl, elles sont maintenant standardisées et disponibles dans presque tous les langages de programmation. Il s’agit d’un outil puissant pour travailler avec toute forme de texte. Dans le cas du scientifique ou de l’ingénieur, je nomme les situations suivantes:

  • Traiter des séries de fichiers de façons générales
  • Isoler des dates

Par exemple: Vous voulez extraire le nom et prénom d’une personne dans le texte suivant:

Côté, Daniel

Vous voulez donc le mot avant la virgule, ensuite, après les espaces, l’autre mot. Vous pourriez lire les caractères un à un, mais qu’arrive-til si vous avez le nom suivant?

De Koninck, Yves

L’analyse peut devenir de plus en plus compliquée et tordue. Ainsi, plutôt que de lire les caractères un à un et de faire l’analyse, vous pouvez utiliser les expressions régulières qui ont été inventées justement pour décrire ce genre de patrons. Dans le cas présent, vous pourriez rapidement extraire le nom et prénom avec l’expression régulière suivante:

\s*(\S.+?),\s*(\S.*?)\s*

Les parenthèses dans les expression régulières représentent les matching groups. Dans notre cas, la première expression entre parenthèses est le nom, la deuxième le prénom, sans les espaces qui peuvent être présents ou non avant ou après le nom. Dans le premier cas, on aurait “Côté” et “Daniel”, alors qu’on aurait “De Koninck” et “Yves” dans le deuxième.

Le langage de base des expressions régulières

Dans leur forme la plus simple, une expression régulière est une suite de caractères avec un indicatif de répétition. Les parenthèses de capture permettent de garder le texte reconnu. On peut ensuite y référer d’une façon qui dépend de l’outil de programmation utilisé ($1, $2, … dans Perl, \1 \2, … dans la boite “Find” de TexWrangler, etc…).

Expression Signification Expression Signification
. N’importe quel caractère * 0 ou plusieurs fois
\s Espace blanc (ou tabulation) + 1 un plusieurs fois
\S Tout sauf un espace blanc ? 0 ou 1 fois
\d Un chiffre {n} n fois
\D Tout sauf un chiffre {n,m} entre n et m fois
^ Début de ligne *? 0 ou plusieurs fois, mais priorité au prochain patron
$ Fin de ligne () Parenthèses de capture
Lettre ou chiffre La lettre ou le chiffre (?:) Paranthèse de regroupement sans capture
\. Le point
\\ Le caractère \

Exemples d’expressions régulières

Objet recherché Expression
Un nom de fichier (.\*?)\\.(...)
Un nom de fichier avec le chemin complet (.\*?)/(.\*?)\\.(...)
Une date de la forme AAA-MM-JJ (\\d{4})-(\d\d)-(\d\d)
Un nom de fichier sous la forme fichier-XXX-YYY-ZZZ.tif ou XXX, YYY et ZZZ sont des chiffres fichier-(\\d{3})-(\\d{3})-(\\d{3})\\.tif{1,2}

Où trouve-t-on les regexps ?

MATLAB

Pour obtenir determiner si du texte coorespond a une expression

matchStr = regexp(filename, ’fichier-\d\d\d-\d\d\d-\d\d\d\.tif{1,2}’,'match')

matchStr aura chaque string qui correspond à l’expression. Pour extraire du texte avec les groupes de capture (i.e. les parenthèses), MATLAB a deux méthodes: par l’ordre ou par nom. Par l’ordre, on fait ceci:

[tokens,matches] = regexp(‘stack-001-002-003.tif’,stack-(\d\d\d)-(\d\d\d)-(\d\d\d)\.tif{1,2},’tokens’,’match’);

tokens{1} aura le premier groupe de capture et ainsi de suite (dans le cas ici: ‘001’, ‘002’, ‘003’), et matches{1} aura la chaine de caractères qui a correspondu en premier (dans le cas ici la chaine au complet), ensuite matches{2} aurait la deuxième s’il y a lieu, etc… L’autre méthode fait appel aux “named tokens”. Ce n’est pas standard regexp, mais MATLAB le fait ainsi:

expressionRegexp = ‘(?\d+)/(?\d+)/(?\d+)’

str = '01/11/2000 20-02-2020 03/30/2000 16-04-2020';

expression = ['(?\d+)/(?\d+)/(?\d+)|(?\d+)-(?\d+)-(?\d+)'];

tokenNames = regexp(str,expression,’names');

MATLAB retournera un array de structures avec chaque element de la structure identifié par month, day ou year:tokenNames(1).month. Plus d’information, tapez dans la fenêtre de commande de MATLAB:doc regexp

Les editeurs de texte

La boite Find de BBEdit/TextWrangler/SublimteText/Emacs, permettent de trouver du texte avec des expressions régulières, mais aussi de le remplacer. Par exemple, avec TextWrangler, changer les commentaires dans du texte de C++ à C. Chaque groupe de capture peut être utiliser dans la boîte de remplacement avec \1, \2, \3 etc…:

textWrangler

Python

Python supporte les expressions régulières. On les utilise comme suit pour extraire les valeurs numériques dans une table de deux colonnes dans un fichier Markdown (par exemple:| 2.0 | 4.0 | mais aussi | .02 | 0.01 |):

matchObj = re.match( "\\|\s*(\.?\d+\.?\d*)\s*\\|\s*(\.?\d+\.?\d*)\s*", line)
if matchObj:
value = float(matchObj.group(1))
x.append(value)
value = float(matchObj.group(2))
y.append(value)
continue

Perl

Perl est bâti autour des expressions régulières. On les utilise comme suit:

if ( $text =~ /(?:+1)?\d{3}?\s*(\d{3}-?\d{4})/ ) {
print “Your phone number without area code is $1”;
}

Plus d’information, tapez dans un terminal Unix: perldoc perlre

Cocoa (iOS ou macOS)

Il existe une classe NSRegularExpression pour faire la reconnaissance de texte. Pour plus d’information, NSRegularExpression dans XCode.

Javascript

Les expressions regulières sont supportés directement dans le langage Javascript. Pour plus d’information: <http://www.w3schools.com/jsref/jsref_obj_regexp.asp>

Mot de la fin

Les expressions régulières sont puissantes et permettent de rapidement vous concentrer sur votre tâche plutôt que de gérer les mondanités ennuyantes des nomenclatures de fichiers, ou les détails d’un texte.

Pour encore plus d’information, “regular expression” dans Google avec le nom de votre langage de choix.

Congratulations Damon DePaoli

Damon received the “Best Overall Poster Presentation” award at the Canadian Neuromodulation Society 10th Annual Scientific Meeting that was held on February 4-6, 2018 in Whistler, British Columbia. The title of his poster : Fiber-based tissue identification for electrode placement in deep brain stimulation neurosurgery.

 

Daniel Côté's laboratory at Neurophotonics Center, Centre de Recherche de l'Institut Universitaire en Santé Mentale de Québec