var ss= "<pre>aaaa\nbbb\nccc</pre>ddd";
var arr= ss.match( /<pre.*?<\/pre>/gm );
alert(arr); // null
Chciałbym, aby blok PRE został pobrany, nawet jeśli obejmuje on znaki nowego wiersza. Myślałem, że flaga „m” to robi. Nie.
Znalazłem odpowiedź tutaj przed opublikowaniem. Kiedy pomyślałem, że znam JavaScript (przeczytałem trzy książki, przepracowałem godziny) i nie było w SO żadnego rozwiązania, odważę się napisać. rzucaj kamieniami tutaj
Tak więc rozwiązaniem jest:
var ss= "<pre>aaaa\nbbb\nccc</pre>ddd";
var arr= ss.match( /<pre[\s\S]*?<\/pre>/gm );
alert(arr); // <pre>...</pre> :)
Czy ktoś ma mniej tajemniczy sposób?
Edycja: to jest duplikatem, ale ponieważ jest to trudniejsze do znalezienia niż moje, ja nie usuwać.
Proponuje się [^]
jako „kropkę wielowierszową”. Nadal nie rozumiem, dlaczego [.\n]
nie działa. Domyślam się, że jest to jedna ze smutnych części JavaScript.
javascript
regex
akauppi
źródło
źródło
Odpowiedzi:
[.\n]
nie działa, ponieważ.
nie ma żadnego specjalnego znaczenia[]
, oznacza po prostu dosłowność.
.(.|\n)
byłby sposób na określenie „dowolnego znaku, w tym nowego wiersza”. Jeśli chcesz dopasować wszystkie znaki nowej linii, musisz również dodać,\r
aby uwzględnić zakończenia linii w stylu Windows i Mac OS:(.|[\r\n])
.To okazuje się nieco kłopotliwe, a także powolne (szczegóły w odpowiedzi KrisWebDev ), więc lepszym rozwiązaniem byłoby dopasowanie wszystkich znaków spacji i wszystkich znaków spacji
[\s\S]
którymi, które będą pasować do wszystkiego, i jest szybszy i prostsze.Zasadniczo nie należy próbować używać wyrażenia regularnego w celu dopasowania do rzeczywistych tagów HTML. Zobacz na przykład te pytania aby uzyskać więcej informacji o tym, dlaczego.
Zamiast tego spróbuj przeszukać DOM w poszukiwaniu potrzebnego znacznika (użycie jQuery ułatwia to, ale zawsze możesz to zrobić
document.getElementsByTagName("pre")
ze standardowym DOM), a następnie przeszukaj zawartość tekstową wyników za pomocą wyrażenia regularnego, jeśli chcesz dopasować do zawartości .źródło
[\r\n]
zastosowane do sekwencji \ r \ n, najpierw pasowałoby \ r, a następnie \ n. Jeśli chcesz dopasować całą sekwencję naraz, niezależnie od tego, czy jest to sekwencja \ r \ n czy tylko \ n, użyj wzoru.|\r?\n
[\s\S]+
..
wewnątrz[]
jest inna niż inne frameworki wyrażeń regularnych, szczególnie zaawansowana w .NET. Ludzie, proszę nie zakładać, że wyrażenia regularne są wieloplatformowe, często nie są !!NIE używaj
(.|[\r\n])
zamiast.
dopasowywania wielowierszowego.UŻYWAJ
[\s\S]
zamiast.
dopasowywania wielowierszowegoUnikaj także zachłanności, gdy nie jest to konieczne, używając
*?
lub+?
kwantyfikatora zamiast*
lub+
. Może to mieć ogromny wpływ na wydajność.Zobacz test, który wykonałem: http://jsperf.com/javascript-multiline-regexp-workarounds
Uwaga: Możesz także użyć,
[^]
ale jest to przestarzałe w poniższym komentarzu.źródło
[^]
. Z jednej strony JavaScript jest jedynym znanym smakiem, który obsługuje ten idiom, a nawet tam jest używany tak często jak[\s\S]
. Z drugiej strony, większość innych smaków pozwala ci uciec przed]
listą. Innymi słowy, w JavaScript[^][^]
pasują dowolne dwa znaki, ale w .NET pasuje dowolny jeden znak inny niż]
,[
lub^
.\S
będzie pasować\r
albo\n
kontra innej postaci?[\s\S]
spośród innych, takich jak[\d\D]
lub[\w\W]
?/<p>Can[^]*?<\/p>/
nie pasuje do tej samej treści co/<p>Can[^]*<\/p>/
. Chciwy wariant należy zmienić,/<p>(?:[^<]|<(?!\/p>))*<\/p>/
aby pasował do tej samej treści.Nie określasz swojego środowiska i wersji Javascript (ECMAscript) i zdaję sobie sprawę, że ten post pochodzi z 2009 roku, ale dla kompletności, dzięki wydaniu ECMA2018 możemy teraz użyć
s
flagi,.
aby dopasować „\ n”, patrz https : //stackoverflow.com/a/36006948/141801A zatem:
Jest to najnowszy dodatek i nie będzie działać w wielu obecnych środowiskach, na przykład wydaje się, że Node v7.7.0 go nie rozpoznaje, ale działa w Chromium i używam go w teście maszynopisu, który piszę i prawdopodobnie z czasem stanie się coraz bardziej popularny.
źródło
[.\n]
nie działa, ponieważ kropka[]
(z definicji wyrażenia regularnego; nie tylko javascript) oznacza znak kropki. Zamiast tego możesz użyć(.|\n)
(lub(.|[\n\r])
).źródło
[\s\S]
jest najczęstszym idiomem JavaScript do dopasowania wszystkiego, w tym nowych linii. To jest łatwiejsze dla oczu i znacznie bardziej wydajne niż podejście oparte na naprzemienności(.|\n)
. (To dosłownie oznacza „każdą postać, która jest spacją lub każdą postacią, która nie jest spacją.”.
, a\n
, i dlaczego[.\n]
nie działa. Jak wspomniano w pytaniu,[^]
jest to również miłe podejście.Przetestowałem to (Chrome) i działa dla mnie (zarówno
[^]
i[^\0]
), zmieniając kropkę (.
) o jeden[^\0]
lub[^]
, ponieważ kropka nie pasuje do podziału linii (patrz tutaj:http://www.regular-expressions.info/dot.html ).źródło
[^\0]
polega na tym, że nie będzie pasował do znaków zerowych, mimo że w ciągach JavaScript dozwolone są znaki puste (patrz ta odpowiedź ).Oprócz wyżej wymienionych przykładów jest to alternatywa.
Gdzie
\w
jest dla słów i\s
białych znakówźródło