philos Δημοσ. 3 Φεβρουαρίου 2015 Δημοσ. 3 Φεβρουαρίου 2015 (επεξεργασμένο) Έχουμε το εξής τμήμα κώδικα που εντοπίζει αν κάποιος χρήστης προσπαθεί να στείλει προσωπικό μήνυμα στο σύστημα Chat με την εντολή /pm η οποία συντάσσεται ως εξής: /pm {username or userid} ; {message}(χωρίς τις αγκύλες) Σας παραθέτω τον κώδικα: if (preg_match("#^(/pm\s+)(.+?[^;]);(.+?)$#i", $message, $matches)) { $this->doshout = false; $user = htmlspecialchars_uni(addslashes(trim($matches[2]))); $user = addslashes(convert_urlencoded_unicode($user)); if ($pmuser = $this->vbulletin->db->query_first("select userid, username from " . TABLE_PREFIX . "user where userid='$user' or username='$user'")) { $this->doshout = true; $this->private = $pmuser['userid']; $message = trim($matches[3]); } }Υπάρχει όμως το εξής πρόβλημα: αν το {message} είναι κείμενο πολλών γραμμών (πχ από copy/paste), τότε δεν περνάει τον έλεγχο της preg_match το μήνυμα και αντί να πάει σε pm, δημοσιεύεται στο κεντρικό chat (για να σας βάλω στο πρόβλημα).Πως μπορώ να το διορθώσω; Έχω μια δυσκολία με τις regular expressions. Ευχαριστώ! Επεξ/σία 3 Φεβρουαρίου 2015 από philos
defacer Δημοσ. 3 Φεβρουαρίου 2015 Δημοσ. 3 Φεβρουαρίου 2015 Πρώτα δυο λόγια γι' αυτό που ήδη έχεις. #^(/pm\s+)(.+?[^;]);(.+?)$#i Στο πράσινο δε χρειάζεσαι παρενθέσεις γιατί δε σ' ενδιαφέρει να κάνεις capture. Αν κάνει match τότε ξέρεις πως πρόκειται για πμ έτσι κι αλλιώς. Οπότε γίνεται /pm\s+ Στο μπλε ζητάς ένα ή περισσότερους χαρακτήρες και μετά κάτι που δεν είναι ερωτηματικό. Αυτό πρώτον δεν έχει πολύ νόημα -- το φορσάρεις να μην τελειώνει σε δύο ερωτηματικά, αλλά ποιός ο λόγος από τη στιγμή που επιτρέπεις δύο ερωτηματικά νωρίτερα; Κατά τη γνώμη μου θα έπρεπε να είναι απλώς (.+?) Στο κόκκινο σου έχει μείνει "από συνήθεια" το nongreedy quantifier αλλά δεν έχει νόημα μιας και αμέσως μετά ακολουθεί unconditional τέλος εισόδου. Θα έπρεπε να είναι απλώς (.+) και πριν από αυτό καλύτερα βάλε και \s* για να φάει τα τυχόν extra spaces. Τώρα όσον αφορά αυτό που ρώτησες, το πρόβλημά σου είναι ότι το . κάνει match οποιοδήποτε χαρακτήρα εκτός από newline. Επομένως το κόκκινο pattern σταματάει πριν το πρώτο newline και επειδή εκεί που σταματάει δεν ακολουθεί το τέλος του string αποτυγχάνει το match συνολικά. Εσύ θέλεις και τα newlines, επομένως το μόνο που έχεις να κάνεις είναι να βάλεις και το s modifier στο τέλος: #/pm\s+(.+?);\s*(.+)$#si 1
lion2486 Δημοσ. 3 Φεβρουαρίου 2015 Δημοσ. 3 Φεβρουαρίου 2015 δεν το έχω πολύ με τις κανονικές εκφράσεις αλλά φαντάζομαι ότι το πρόβλημά της θα είναι με τους χαρακτήρες αλλαγής γραμμής, αν δοκίμαζες ένα trim() στο message πριν την if σου;;
paparovic Δημοσ. 4 Φεβρουαρίου 2015 Δημοσ. 4 Φεβρουαρίου 2015 Πρώτα δυο λόγια γι' αυτό που ήδη έχεις. #^(/pm\s+)(.+?[^;]);(.+?)$#i Στο πράσινο δε χρειάζεσαι παρενθέσεις γιατί δε σ' ενδιαφέρει να κάνεις capture. Αν κάνει match τότε ξέρεις πως πρόκειται για πμ έτσι κι αλλιώς. Οπότε γίνεται /pm\s+ Στο μπλε ζητάς ένα ή περισσότερους χαρακτήρες και μετά κάτι που δεν είναι ερωτηματικό. Αυτό πρώτον δεν έχει πολύ νόημα -- το φορσάρεις να μην τελειώνει σε δύο ερωτηματικά, αλλά ποιός ο λόγος από τη στιγμή που επιτρέπεις δύο ερωτηματικά νωρίτερα; Κατά τη γνώμη μου θα έπρεπε να είναι απλώς (.+?) Στο κόκκινο σου έχει μείνει "από συνήθεια" το nongreedy quantifier αλλά δεν έχει νόημα μιας και αμέσως μετά ακολουθεί unconditional τέλος εισόδου. Θα έπρεπε να είναι απλώς (.+) και πριν από αυτό καλύτερα βάλε και \s* για να φάει τα τυχόν extra spaces. Τώρα όσον αφορά αυτό που ρώτησες, το πρόβλημά σου είναι ότι το . κάνει match οποιοδήποτε χαρακτήρα εκτός από newline. Επομένως το κόκκινο pattern σταματάει πριν το πρώτο newline και επειδή εκεί που σταματάει δεν ακολουθεί το τέλος του string αποτυγχάνει το match συνολικά. Εσύ θέλεις και τα newlines, επομένως το μόνο που έχεις να κάνεις είναι να βάλεις και το s modifier στο τέλος: #/pm\s+(.+?);\s*(.+)$#si Λείπει ένα \ στην αρχή (\/pm..) αλλά εξαιρετική απάντηση.
defacer Δημοσ. 4 Φεβρουαρίου 2015 Δημοσ. 4 Φεβρουαρίου 2015 Λείπει ένα \ στην αρχή (\/pm..) αλλά εξαιρετική απάντηση. Δε χρειάζεται επειδή χρησιμοποιεί το # σαν delimiter 1
Προτεινόμενες αναρτήσεις
Δημιουργήστε ένα λογαριασμό ή συνδεθείτε για να σχολιάσετε
Πρέπει να είστε μέλος για να αφήσετε σχόλιο
Δημιουργία λογαριασμού
Εγγραφείτε με νέο λογαριασμό στην κοινότητα μας. Είναι πανεύκολο!
Δημιουργία νέου λογαριασμούΣύνδεση
Έχετε ήδη λογαριασμό; Συνδεθείτε εδώ.
Συνδεθείτε τώρα