Domanda

La stringa di testo che voglio per convalidare è costituito da quello che io chiamo "segmenti". Un singolo segmento potrebbe essere simile a questo:

 [A-Z,S,3]

Finora sono riuscito a costruire questo schema di espressione regolare

(?:\[(?<segment>[^,\]\[}' ]+?,[S|D],\d{1})\])+?

funziona, ma tornerà partite, anche se l'intera stringa di testo contiene testo non valido. Credo che ho bisogno di usare ^ e $ qualche parte nel mio modello, ma io non riesco a capire come!?

Vorrei che il mio modello per produrre i seguenti risultati:

  • [A-Z,S,3][A-Za-z0-9åäöÅÄÖ,D,4] OK (due segmenti)
  • [A-Z,S,3]aaaa[A-Za-z0-9åäöÅÄÖ,D,4] Nessuna corrispondenza
  • crap[A-Z,S,3][A-Za-z0-9åäöÅÄÖ,D,4] Nessuna corrispondenza
  • [A-Z,S,3][] Nessuna corrispondenza
  • [A-Z,S,3][klm,D,4][0-9,S,1] OK (tre segmenti)
È stato utile?

Soluzione

Usa ^ per ancorare l'inizio e $ per l'ancoraggio alla fine. Es .: ^(abc)*$, questo corrisponde a zero o più ripetizioni del gruppo ( "abc" in questo esempio) e che deve iniziare all'inizio della stringa di input e terminano alla fine di esso.

^(?:[(?[^,][}' ]+?,[S|D],\d{1})])+$-utilizzando un +? ungreedy non importa, come si richiede in modo che corrisponda fino alla fine in ogni caso. Tuttavia, il vostro regex ha alcuni problemi.

^(?:\[[^,]+,[SD],\d\])+$-sembra più simile a ciò che si desidera.

  • non ho potuto decifrare ciò che si intende per la prima parte, quindi il mio regex è più generale di quanto richiesto, [^,]+, corrisponderà a qualsiasi sequenza di non-virgole seguito da una virgola, e in effetti si dovrebbe probabilmente aggiungere ] a questa negata classe di caratteri.
  • [S|D] è una classe di caratteri di tre personaggi, come | non significa alternanza qui ((S|D) significherebbe lo stesso [SD] però).
  • {1} è l'impostazione predefinita per qualsiasi atomo, non è necessario specificarlo.

Pseudocodice (eseguirlo a codepad.org ):

import re
def find_segments(input_string):
  results = []
  regex = re.compile(r"\[([^],]+),([SD]),(\d)\]")
  start = 0
  while True:
    m = regex.match(input_string, start)
    if not m: # no match
      return None # whole string didn't match, do another action as appropriate
    results.append(m.group(1, 2, 3))
    start = m.end(0)
    if start == len(input_string):
      break
  return results

print find_segments("[A-Z,S,3][klm,D,4][0-9,S,1]")
# output:
#[('A-Z', 'S', '3'), ('klm', 'D', '4'), ('0-9', 'S', '1')]

La grande differenza qui è l'espressione corrisponde solo la parte completa [...], ma viene applicato in successione, quindi devono ricominciare dove gli ultimi estremità (o estremità alla fine della stringa).

Altri suggerimenti

Si desidera qualcosa di simile:

/^(\[[^],]+,[SD],\d\])+$/

Ecco un esempio di come si potrebbe usare questa espressione regolare in C #:

using System;
using System.Text.RegularExpressions;

class Program
{
    static void Main(string[] args)
    {
        string[] tests = {
            "[A-Z,S,3][A-Za-z0-9,D,4]",
            "[A-Z,S,3]aaaa[A-Za-z0-9,D,4]",
            "crap[A-Z,S,3][A-Za-z0-9,D,4]",
            "[A-Z,S,3][]",
            "[A-Z,S,3][klm,D,4][0-9,S,1]"
        };

        string segmentRegex = @"\[([^],]+,[SD],\d)\]";
        string lineRegex = "^(" + segmentRegex + ")+$";

        foreach (string test in tests)
        {
            bool isMatch = Regex.Match(test, lineRegex).Success;
            if (isMatch)
            {
                Console.WriteLine("Successful match: " + test);
                foreach (Match match in Regex.Matches(test, segmentRegex))
                {
                    Console.WriteLine(match.Groups[1]);
                }
            }
        }
    }
}

Output:

Successful match: [A-Z,S,3][A-Za-z0-9,D,4]
A-Z,S,3
A-Za-z0-9,D,4
Successful match: [A-Z,S,3][klm,D,4][0-9,S,1]
A-Z,S,3
klm,D,4
0-9,S,1
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top