Wie kann man Zeichen abwechselnd prüfen und durch Y ersetzen, wenn es X ist?

8

Ich habe eine Zeichenfolge, etwa so:

%Vor%

Jetzt muss ich alle Zeichen überprüfen, die Vielfache von 4 sind (plus das erste Zeichen) . wie diese:

%Vor%

Jetzt muss ich sie mit Y vergleichen ( Y ist eine Variable (Symbol), zum Beispiel Y = 'r' hier) . Also ich möchte Y durch X ersetzen ( X ist auch eine Variable (Symbol), zum Beispiel X = 'm' hier).

Also, ich möchte diese Ausgabe:

%Vor%

Hier ist meine Lösung : Ich kann das mit einer PHP Funktion machen:

  • strlen($str) : Zählt die Anzahl der Zeichen (named $sum )
  • $sum / 4 : Um Zeichen zu finden, die ein Vielfaches von 4 sind
  • substr($str, 4,1) : Zum Auswählen eines bestimmten Zeichens (benannt $char ) {das Problem ist hier}
  • if ($char == 'r') {} : Vergleichen
  • str_replace('r','m',$char) : um
  • zu ersetzen

Und dann alle $char miteinander kombinieren.

Aber meine Lösung hat zwei Probleme :

  1. substr() zählt nicht [space] character (Wie oben erwähnt)
  2. Kombinieren von Zeichen ist ein wenig kompliziert. (Es muss etwas Abfall verarbeitet werden)

Nun, gibt es eine Lösung? Ich mache das gerne mit REGEX, ist das möglich?

    
Shafizadeh 16.11.2015, 07:29
quelle

7 Antworten

4

Dies ist eine Alternative mit preg_replace ()

%Vor%

ideone-Demo

Regex:

%Vor%
  • \G ist eine Assertion bis zum Ende der letzten Übereinstimmung (oder Start des Strings)
  • (?:^|(?(?<!^.).)..(?:.{4})*?) entspricht:
    • ^ Anfang des Strings, um an Position 1 zu prüfen
    • (?(?<!^.).) ist eine if-Klausel, die Folgendes liefert:
      1. ..(?:.{4})*?) 2 Zeichen + ein Vielfaches von 4, wenn es gerade an Position 1 ersetzt wurde
      2. ...(?:.{4})*?) 3 Zeichen + ein Vielfaches von 4 für aufeinanderfolgende Übereinstimmungen
  • \K setzt den übereinstimmenden Text zurück, um die Verwendung von Rückverweisen zu vermeiden

Ich muss allerdings sagen, Regex ist ein Overkill für diese Aufgabe. Dieser Code ist nicht intuitiv und eine typische Regex, die schwer zu verstehen / zu debuggen / zu warten ist.

BEARBEITEN . Es gab eine spätere Diskussion über die Lesbarkeit von Performance und Code, also habe ich einen Benchmark zum Vergleichen gemacht:

  1. RegEx mit einem Rückruf ( @ bobblebubbles Antwort ).
  2. RegEx mit 2 Ersetzungen in einem Array ( @ bobblebubbles Vorschlag im Kommentar ).
  3. Keine RegEx mit substr_replace ( @ Passerys Antwort ).
  4. Pure RegEx (diese Antwort).

Ergebnis:

%Vor%

Benchmark in ideone.com

    
Mariano 16.11.2015, 09:57
quelle
8

Könnte einfach einen einfachen Regex mit callback (füge u hinzu Modifikator wenn utf-8, s für . , um mit Newline zu übereinstimmen).

%Vor%
  

es ist ein Test stming.

  • 1. Muster: ^. jedes erste Zeichen
  • 2. Muster: \K setzt nach .{3} alle drei Zeichen zurück und möchte nur den vierten . überprüfen

Siehe Demo bei eval.in

Für die Verwendung mit anonymer Funktion ist PHP & gt; = 5.3 erforderlich. Hier ist die Problemumgehung.

%Vor%

Noch eine Demo bei eval.in

    
bobble bubble 16.11.2015 08:43
quelle
5

Wenn alle Zeichen in Ihrer Zeichenfolge in einem einzelnen Byte sind, können Sie etwas aus Offizielle Sprachreferenz von PHP :

%Vor%

3v4l-Demo

Ausgaben it is a test stming.

Bearbeiten:

Wie @Don'tPanic darauf hinweist, ist String mit [] operator veränderbar, anstatt

zu verwenden %Vor%

kannst du einfach

verwenden %Vor%     
Passerby 16.11.2015 07:54
quelle
4

Versuchen Sie es

%Vor%     
Drop Shadow 16.11.2015 07:47
quelle
1

Dieser Code könnte Ihnen auf Ihrem Weg helfen:

%Vor%     
Peter 16.11.2015 07:52
quelle
1

Hier ist eine andere Möglichkeit, dies zu tun mit String-Zugriff und Modifikation nach Charakter . (Folglich ist es nur für single-byte codierte Strings nützlich.)

%Vor%

Dies ändert die ursprüngliche Zeichenkette, anstatt eine neue Zeichenkette zu erstellen. Wenn dies nicht passieren sollte, sollte sie in einer Kopie verwendet werden.

    
Don't Panic 04.04.2016 23:50
quelle
1

Spät zur Party, \G anker beiseite legen, würde ich mit (*SKIP)(*F) Methode gehen:

%Vor%

Kurz und sauber.

PHP Live-Demo

    
revo 18.11.2017 22:32
quelle

Tags und Links