2016-04-27 3 views
4

Ich habe eine Gruppe von variablen var:R regex: Entfernen von „*“ nur zwischen einer Gruppe von Variablen

> var 
[1] "a1" "a2" "a3" "a4" 

hier ist das, was ich erreichen möchte: regex und Strings zu ändern, wie dies :

3*a1 + a1*a2 + 4*a3*a4 + a1*a3 

zu

3a1 + a1*a2 + 4a3*a4 + a1*a3 

Grundsätzlich möchte ich trimmen "*", die nicht zwischen irgendwelchen Werten in var. Vielen Dank im Voraus

+0

'gsub ('(\\ d) \\ * (\\ w)', '\\ 1 \\ 2',‚3 * a + a * b + 4 * c * d + a * c ') vielleicht – alistaire

+0

In deiner "Change' x' zu 'y'", weder 'x' noch' y' sind Objekte in R, so ist es nicht klar, was du bist fragend. – Frank

+0

Warum negative Stimmen? Hast du eine Antwort dafür? Oder einfach nur beleidigend und einstimmig bleiben? – BlueFeet

Antwort

3

Kann tun (?<![\da-z])(\d+)\*$1

(?<! [\da-z]) 
(\d+)      # (1) 
\* 

Oder ((?:[^\da-z]|^)\d+)\* für die Behauptung beeinträchtigt Motoren

(       # (1 start) 
     (?: [^\da-z] | ^) 
     \d+ 
)        # (1 end) 
\* 

Führende Behauptungen sind schlecht ersetzen zu finden sowieso.

Benchmark

Regex1: (?<![\da-z])(\d+)\* 
Options: <none> 
Completed iterations: 100/100  (x 1000) 
Matches found per iteration: 2 
Elapsed Time: 1.09 s, 1087.84 ms, 1087844 µs 


Regex2: ((?:[^\da-z]|^)\d+)\* 
Options: <none> 
Completed iterations: 100/100  (x 1000) 
Matches found per iteration: 2 
Elapsed Time: 0.77 s, 767.04 ms, 767042 µs 
+0

' Fehler: unerwartet' <'in "(? <" ' – rawr

+0

@rawr - Hmm, Behauptungen .. – sln

2

Sie können aus dem var eine dynamische regex erstellen und * s zu erfassen zu entsprechen, die in Ihrem Variablen sind, und legen Sie sie in gsub mit einem Rückverweis zurück, und entfernen Sie alle anderen Sternchen:

var <- c("a1","a2","a3","a4") 
s = "3*a1 + a1*a2 + 4*a3*a4 + a1*a3" 
block = paste(var, collapse="|") 
pat = paste0("\\b((?:", block, ")\\*)(?=\\b(?:", block, ")\\b)|\\*") 
gsub(pat, "\\1", s, perl=T) 
## "3a1 + a1*a2 + 4a3*a4 + a1*a3" 

Siehe IDEONE demo

H ere ist die regex:

\b((?:a1|a2|a3|a4)\*)(?=\b(?:a1|a2|a3|a4)\b)|\* 

Details:

  • \b - führende Wortgrenze
  • ((?:a1|a2|a3|a4)\*) - Gruppe 1 passend
    • (?:a1|a2|a3|a4) - entweder eine Ihrer Variablen
    • \* - Sternchen
    • (?=\b(?:a1|a2|a3|a4)\b) - ein Look-Ahead-Check, dass es eine Ihrer Variablen sein (andernfalls wird keine Übereinstimmung zurückgegeben, die * mit dem zweiten Zweig des Wechsels angepasst)
  • | - oder
  • \* - ein "wildes" wörtliches Sternchen, das entfernt werden soll.
+1

Dies ist die beste Lösung so weit, danke! – BlueFeet

1

die Gleichung als String machen, ist eine Option,

gsub('((?:^|)\\d)\\*(\\w)', '\\1\\2', '3*a1 + a1*a2 + 4*a3*a4 + a1*a3') 
# [1] "3a1 + a1*a2 + 4a3*a4 + a1*a3" 

die

  • ein aufgenommenes Gruppe von Zeichen für

    sieht, (...)
    • eine nicht-einfangende Gruppe enthält, , (?: ...)
      • den Anfang der Zeile mit ^
      • oder |
      • einen Raum (oder \\s)
    • gefolgt von einer Ziffer 0-9, \\d.
  • Die Erfassungsgruppe durch ein Sternchen folgt, \\*,
  • durch eine andere Erfassungsgruppe gefolgt (...)
    • ein alphanumerisches Zeichen enthält \\w.

Sie ersetzt die oben mit

  • ersten erfassten Gruppe, \\1,
  • von der zweiten Gruppe gefolgt erfasst, \\2.

Bei Bedarf anpassen.

0

Dank @alistaire für das Angebot einer Lösung mit nicht einfangender Gruppe. Die Lösung antwortet jedoch darauf, dass ein Abstand zwischen dem Koeffizienten und "+" davor existiert. Hier ist meine modifizierte Lösung auf seinen Vorschlag basiert:

> ss <- "3*a1 + a1*a2+4*a3*a4 +2*a1*a3+ 4*a2*a3" 
# my modified version 
> gsub('((?:^|\\s|\\+|\\-)\\d)\\*(\\w)', '\\1\\2', ss) 
[1] "3a1 + a1*a2+4a3*a4 +2a1*a3+ 4a2*a3" 

# alistire's 
> gsub('((?:^|)\\d)\\*(\\w)', '\\1\\2', ss) 
[1] "3a1 + a1*a2+4*a3*a4 +2*a1*a3+ 4a2*a3" 
+0

Es ist ein wenig verwirrend, um zu sehen, dass Sie in der Validierung vor der Ziffer spezifisch sein müssen, und warum es wirklich notwendig ist, nach dem Sternchen. Gewöhnlich ist die Art, es zu tun, es zu beschränken, was bekannt ist, dh sollte nicht vor der Ziffer sein, andernfalls implizieren Sie, dass Sie der Zeichenkette nicht vertrauen, in diesem Fall sollten Sie die gesamte Zeichenkette vor der Ersetzung validieren – sln

+0

Der Benutzer kann eine Variable namens "4a" haben, also kann ich nicht einfach sagen "sollte nicht vor der Ziffer" – BlueFeet

Verwandte Themen