JavaScript RegEx - повертає результат, але все ще не працює

Я намагаюся збігти з вузлом DTD, таким як цей текст


За допомогою цього регулярного виразу:

match(//i)

і він повертає потрібний текст + текст 'note' -може пояснити, чому?

Крім того, коли я видаляю будь-який або обидва пробіли з обох сторін тексту 'note', він все одно повертає результат, і це не потрібно. Чи може хто-небудь допомогти пояснити, чому це теж робить?

Ось тестовий файл:

,
,
,
,
,
,
,
,
,
,
,
,

Заздалегідь дякую за будь-яку допомогу!

2
@ Bergi, заснований на коментарі до відповіді zmo, я припускаю, що OP бажає відповідати будь-якому вузлу елемента DTD.
додано Автор Derek S. Henderson, джерело
@ Bergi, заснований на коментарі до відповіді zmo, я припускаю, що OP бажає відповідати будь-якому вузлу елемента DTD.
додано Автор Derek S. Henderson, джерело
Покажіть нам, як ви використовуєте цей регулярний вираз - це, здається, працює. Що хочемо ?
додано Автор Bergi, джерело
Покажіть нам, як ви використовуєте цей регулярний вираз - це, здається, працює. Що хочемо ?
додано Автор Bergi, джерело
Отже, ви тільки хочете підібрати "(to, from, body)"? Чи потрібний елемент записки?
додано Автор Erik Schierboom, джерело
Отже, ви тільки хочете підібрати "(to, from, body)"? Чи потрібний елемент записки?
додано Автор Erik Schierboom, джерело
Я хочу відповідати всім вузлом, якщо він правильно відформатований ... або будь-яким вузлом подібної структури, тому результат у цьому випадку буде наприклад.
додано Автор user1360809, джерело
Я хочу відповідати всім вузлом, якщо він правильно відформатований ... або будь-яким вузлом подібної структури, тому результат у цьому випадку буде наприклад.
додано Автор user1360809, джерело

8 Відповіді

Ось як виглядає звичайний вираз, переглядаючи його через автомат

Regular expression image

Отже, ви дійсно правильно підбираєте те, що хочете, але ви також збираєте дві групи:

  1. "
  2. "note"

але він також буде відповідати іншим видам рядків, наприклад:

які не добре сформовані мітки.

Отже, краще зробити більш точний регулярний вираз , люблю:


  • here's what the regex matches:
    • text
    • \s+ one or more space
    • \w+ one or more in word character
    • \s+ one or more space
    • \( a real parenthesis
    • ( begin of a group
    • \w+ on or more in word character
    • , a comma
    • ? one or zero space (could be * zero or more spaces)
    • )* end of the group, that group being matched zero or more times
    • \w+ one or more in word character
    • (you may want to add \s* if you want to match optional spaces before the closing parenthesis)
    • \) closing parenthesis character
    • (you may want to add \s* if you want to match optional spaces before the end of the tag)
    • > closing tag character

Regular expression image

Then, when you do match(//i), you will still get two groups:

  1. ""
  2. "from,"

і ви повинні отримати першу групу, вам просто потрібно отримати перший елемент повернутого масиву:

var match = "".match(//i);
if (match !== null)
    match = match[0];

і якщо ви хочете використовувати об'єкт регулярного виразу для цього:

pattern = new RegExp(//i)
match = pattern.exec(text)
if (match !== null)
    match = match[0]

що дасть вам першу групу матчу (що є повним матчем).

Після редагування:

потрібно регулярний вираз, який працює на цьому наборі значень:

,
,
,
,
,
,
,
,
,
,
,
,

так що ви хочете мати регулярний вираз, який виглядає так:

//

Regular expression image

переглянути тут

var match = "".match(//i);
if (match !== null)
    match = match[0];

there it matches only the nodes, not the or nodes. For those ones, match will be equal to null. For nodes, they will contain the full string of the matched node.

2
додано
Я отримала чітке враження, що ОР не хотіла збігатися з двома групами, тільки з однією.
додано Автор Derek S. Henderson, джерело
Про образи я їх дуже люблю, тому що вони добре пояснюють, чому регулярний вираз добре чи ні. Regex в основному просто Automaton (точніше NFA). На онлайн-курсах MIT існують чудові курси на тему: про NFA і Regex
додано Автор zmo, джерело
Я тільки що тестував новий RegExp приклад і він працює теж.
додано Автор zmo, джерело
@ user1360809 Ви можете надати нам, що саме у dtdNodes [i] ?
додано Автор zmo, джерело
ОК, так що ваш приклад повністю вводить в оману!
додано Автор zmo, джерело
О, і, до речі, завжди думайте про тестування, якщо відповідність === null перед доступом до елемента масиву!
додано Автор zmo, джерело
тому що всі ми зробили найбільш точний регулярний вираз, щоб він відповідав вашому єдиному прикладу, тоді як ви хотіли відповідати всім вузлом елемента DTD!
додано Автор zmo, джерело
так, це так, тому що це те, що ви просили! Потрібно чітко визначити, що у вас є вхідними даними, і що ви хочете вивести. В основному, ви сказали, що я хочу відповідати (але не або )
додано Автор zmo, джерело
відредагуйте своє запитання, щоб зробити його більш точним щодо того, що ви маєте проти того, що ви хочете
додано Автор zmo, джерело
додано Автор zmo, джерело
дивно, я спробував: js> matches = ''. матч (/ >/i) [0]; і повертає "" . Хоча, я не впевнений у своєму прикладі new RegExp .
додано Автор zmo, джерело
мої вибачення - після вашого редагування / все ще містить частину , заголовок - чи це не було відредаговано для цього?
додано Автор user1360809, джерело
Мої вибачення! Я постараюся бути ясним! І якщо ви побачите вище, ваш regEx повертає "заголовок", а також те, що потрібно :(
додано Автор user1360809, джерело
вибачте (дуже ненавмисне)! як це вводити в оману?
додано Автор user1360809, джерело
це: var testMatch = dtdNodes [i] .match (/ testMatch = , заголовок, - біт testMatch = був текстом, який я додав до мого попередження ()
додано Автор user1360809, джерело
Це те, що в dtdNodes, колекція всіх знайдених вузлів DTD я витягнув з мого тестового файлу: , , , , , , , , , ,
додано Автор user1360809, джерело
це, здається, не працює, хоча чудові зображення! Я спробував використати наступне: var testMatch = dtdNodes [i] .match (/
додано Автор user1360809, джерело

Ось як виглядає звичайний вираз, переглядаючи його через автомат

Regular expression image

Отже, ви дійсно правильно підбираєте те, що хочете, але ви також збираєте дві групи:

  1. "
  2. "note"

але він також буде відповідати іншим видам рядків, наприклад:

які не добре сформовані мітки.

Отже, краще зробити більш точний регулярний вираз , люблю:


  • here's what the regex matches:
    • text
    • \s+ one or more space
    • \w+ one or more in word character
    • \s+ one or more space
    • \( a real parenthesis
    • ( begin of a group
    • \w+ on or more in word character
    • , a comma
    • ? one or zero space (could be * zero or more spaces)
    • )* end of the group, that group being matched zero or more times
    • \w+ one or more in word character
    • (you may want to add \s* if you want to match optional spaces before the closing parenthesis)
    • \) closing parenthesis character
    • (you may want to add \s* if you want to match optional spaces before the end of the tag)
    • > closing tag character

Regular expression image

Then, when you do match(//i), you will still get two groups:

  1. ""
  2. "from,"

і ви повинні отримати першу групу, вам просто потрібно отримати перший елемент повернутого масиву:

var match = "".match(//i);
if (match !== null)
    match = match[0];

і якщо ви хочете використовувати об'єкт регулярного виразу для цього:

pattern = new RegExp(//i)
match = pattern.exec(text)
if (match !== null)
    match = match[0]

що дасть вам першу групу матчу (що є повним матчем).

Після редагування:

потрібно регулярний вираз, який працює на цьому наборі значень:

,
,
,
,
,
,
,
,
,
,
,
,

так що ви хочете мати регулярний вираз, який виглядає так:

//

Regular expression image

переглянути тут

var match = "".match(//i);
if (match !== null)
    match = match[0];

there it matches only the nodes, not the or nodes. For those ones, match will be equal to null. For nodes, they will contain the full string of the matched node.

2
додано
Я отримала чітке враження, що ОР не хотіла збігатися з двома групами, тільки з однією.
додано Автор Derek S. Henderson, джерело
ОК, так що ваш приклад повністю вводить в оману!
додано Автор zmo, джерело
Про образи я їх дуже люблю, тому що вони добре пояснюють, чому регулярний вираз добре чи ні. Regex в основному просто Automaton (точніше NFA). На онлайн-курсах MIT існують чудові курси на тему: про NFA і Regex
додано Автор zmo, джерело
Я тільки що тестував новий RegExp приклад і він працює теж.
додано Автор zmo, джерело
О, і, до речі, завжди думайте про тестування, якщо відповідність === null перед доступом до елемента масиву!
додано Автор zmo, джерело
@ user1360809 Ви можете надати нам, що саме у dtdNodes [i] ?
додано Автор zmo, джерело
тому що всі ми зробили найбільш точний регулярний вираз, щоб він відповідав вашому єдиному прикладу, тоді як ви хотіли відповідати всім вузлом елемента DTD!
додано Автор zmo, джерело
так, це так, тому що це те, що ви просили! Потрібно чітко визначити, що у вас є вхідними даними, і що ви хочете вивести. В основному, ви сказали, що я хочу відповідати (але не або )
додано Автор zmo, джерело
відредагуйте своє запитання, щоб зробити його більш точним щодо того, що ви маєте проти того, що ви хочете
додано Автор zmo, джерело
додано Автор zmo, джерело
дивно, я спробував: js> matches = ''. матч (/ >/i) [0]; і повертає "" . Хоча, я не впевнений у своєму прикладі new RegExp .
додано Автор zmo, джерело
мої вибачення - після вашого редагування / все ще містить частину , заголовок - чи це не було відредаговано для цього?
додано Автор user1360809, джерело
Мої вибачення! Я постараюся бути ясним! І якщо ви побачите вище, ваш regEx повертає "заголовок", а також те, що потрібно :(
додано Автор user1360809, джерело
вибачте (дуже ненавмисне)! як це вводити в оману?
додано Автор user1360809, джерело
це: var testMatch = dtdNodes [i] .match (/ testMatch = , заголовок, - біт testMatch = був текстом, який я додав до мого попередження ()
додано Автор user1360809, джерело
Це те, що в dtdNodes, колекція всіх знайдених вузлів DTD я витягнув з мого тестового файлу: , , , , , , , , , ,
додано Автор user1360809, джерело
це, здається, не працює, хоча чудові зображення! Я спробував використати наступне: var testMatch = dtdNodes [i] .match (/
додано Автор user1360809, джерело

Відповідь на обидві полягає в тому, що ви використовуєте . * , який відповідає всім нуль або більше разів.

Замість цього використовуйте такий регулярний вираз:

//i

Доказ регулярних виразів

Скрипку для подальшої демонстрації роботи

І прекрасний образ, який показує, як працює матч

Regular expression image

To summarize, this matches the string , followed by either ELEMENT or ENTITY or ATTLIST, followed by 1 or more spaces (\s+), followed by 1 or more word characters (\w+), followed by 1 or more spaces, followed by one or more characters, followed by the closing bracket.

1
додано
@ user1360809, з вашого питання не було зрозуміло, що ви хочете відповідати будь-якому дійсному вузлу елемента DTD. Попередня інформація, яку я надав вам, відповідала лише вказаному вами рядку. Я відредагував свою відповідь так, щоб він тепер відповідав будь-якому вузлу елемента DTD.
додано Автор Derek S. Henderson, джерело
Як так? Демо працює.
додано Автор Derek S. Henderson, джерело
Ласкаво просимо. Я радий, що ми змогли знайти те, що працює. :) Будь ласка, прийміть до уваги відповідь. Дякую!
додано Автор Derek S. Henderson, джерело
Регулярні вирази однакові для кожної мови, наскільки я знаю, але існують тонкі відмінності в тому, як вони можуть бути використані. Я дійсно можу тільки зважити на JS, хоча.
додано Автор Derek S. Henderson, джерело
@ user1360809, я оновив свою відповідь, щоб відповідати всім прикладам, які ви даєте з вузлів DTD.
додано Автор Derek S. Henderson, джерело
не знаю - я скопіював RegEx безпосередньо, і він нічого не повертає!
додано Автор user1360809, джерело
так працює зараз спасибі! Ви правильні, я використовую його, щоб вибрати будь-який вузол DTD, якщо він відповідає потрібному формату.
додано Автор user1360809, джерело
цей не працював для мене ...
додано Автор user1360809, джерело
буде робити ... Я ціную час, який потрібно людям, щоб відповісти і спробувати дати їм час назад ... дізналися багато таких, як "захоплення" річ і ефективність не використовують ungreedy quantifiers :) Це те ж саме для кожного мовою або я можу очікувати тонкі відмінності, наприклад?
додано Автор user1360809, джерело

Відповідь на обидві полягає в тому, що ви використовуєте . * , який відповідає всім нуль або більше разів.

Замість цього використовуйте такий регулярний вираз:

//i

Доказ регулярних виразів

Скрипку для подальшої демонстрації роботи

І прекрасний образ, який показує, як працює матч

Regular expression image

To summarize, this matches the string , followed by either ELEMENT or ENTITY or ATTLIST, followed by 1 or more spaces (\s+), followed by 1 or more word characters (\w+), followed by 1 or more spaces, followed by one or more characters, followed by the closing bracket.

1
додано
Регулярні вирази однакові для кожної мови, наскільки я знаю, але існують тонкі відмінності в тому, як вони можуть бути використані. Я дійсно можу тільки зважити на JS, хоча.
додано Автор Derek S. Henderson, джерело
Як так? Демо працює.
додано Автор Derek S. Henderson, джерело
@ user1360809, з вашого питання не було зрозуміло, що ви хочете відповідати будь-якому дійсному вузлу елемента DTD. Попередня інформація, яку я надав вам, відповідала лише вказаному вами рядку. Я відредагував свою відповідь так, щоб він тепер відповідав будь-якому вузлу елемента DTD.
додано Автор Derek S. Henderson, джерело
Ласкаво просимо. Я радий, що ми змогли знайти те, що працює. :) Будь ласка, прийміть до уваги відповідь. Дякую!
додано Автор Derek S. Henderson, джерело
@ user1360809, я оновив свою відповідь, щоб відповідати всім прикладам, які ви даєте з вузлів DTD.
додано Автор Derek S. Henderson, джерело
цей не працював для мене ...
додано Автор user1360809, джерело
так працює зараз спасибі! Ви правильні, я використовую його, щоб вибрати будь-який вузол DTD, якщо він відповідає потрібному формату.
додано Автор user1360809, джерело
буде робити ... Я ціную час, який потрібно людям, щоб відповісти і спробувати дати їм час назад ... дізналися багато таких, як "захоплення" річ і ефективність не використовують ungreedy quantifiers :) Це те ж саме для кожного мовою або я можу очікувати тонкі відмінності, наприклад?
додано Автор user1360809, джерело
не знаю - я скопіював RegEx безпосередньо, і він нічого не повертає!
додано Автор user1360809, джерело

Визначення частини примітки фіксується:

var node = '';
node.match(/';
invalidNode.match(/

See: http://jsfiddle.net/a5KkF/

1
додано

Визначення частини примітки фіксується:

var node = '';
node.match(/';
invalidNode.match(/

See: http://jsfiddle.net/a5KkF/

1
додано

Примітка note знімати . Набори дужок роблять цю частину відповідності доступною пізніше (або в межах зворотних посилань). Оскільки вам не потрібні навіть дужки для групування, просто видаліть їх, якщо ви не хочете, щоб note .

Тоді ваші пробіли є необов'язковими (через ? ) - отже, видалення їх у рядку взагалі не має значення. Просто видаліть ? або зробіть його + (щоб було дозволено більше одного простору).

Інша проблема полягає в тому, що . також може співпадати з пробілами. Можливо, ви повинні бути трохи більш обмежувальними (таким чином ви можете також уникнути ungreedy quantifiers, які, як правило, гірше продуктивності):

//i

\S matches anything except space character and [^)] matches anything except ) characters (it's a negated character class). In fact, you might want to exclude ( from the \S as well, because otherwise it could already match into the parentheses:

//i

If the note part has to contain at least one character you should make that clear in the regex as well, by using + instead of *

//i

Якщо, з іншого боку, частина note є необов'язковою, для моєї попередньої версії потрібно щонайменше 2 пробілів (через два + + ). У такому випадку можна згрупувати частину note разом з наступним простором і зробити її необов'язковою разом. Таким чином, вам знадобиться тільки пробіл, якщо note є. Щоб припинити зйомку (щоб ви не отримали ще два рядки), використовуйте (?: ...) для групування замість (...) :

//i

Зверніть увагу, що матч все одно дасть вам масив, що містить рядок, який ви шукаєте (і ви нічого не можете зробити з цього приводу), тому вам доведеться мати доступ до нього за допомогою [0] .

0
додано
@ user1360809 так, я неправильно зрозумів цю частину вашого питання і відредагував свою відповідь зараз.
додано Автор Martin Ender, джерело
може підтвердити, що він працює! ;) Незважаючи на те, що синтаксис трохи складніший, я віддаю перевагу цій відповіді зараз ...
додано Автор user1360809, джерело
спасибі - вона як і раніше, здається, збігається з пробілами - будь-яка ідея чому?
додано Автор user1360809, джерело

Примітка note знімати . Набори дужок роблять цю частину відповідності доступною пізніше (або в межах зворотних посилань). Оскільки вам не потрібні навіть дужки для групування, просто видаліть їх, якщо ви не хочете, щоб note .

Тоді ваші пробіли є необов'язковими (через ? ) - отже, видалення їх у рядку взагалі не має значення. Просто видаліть ? або зробіть його + (щоб було дозволено більше одного простору).

Інша проблема полягає в тому, що . також може співпадати з пробілами. Можливо, ви повинні бути трохи більш обмежувальними (таким чином ви можете також уникнути ungreedy quantifiers, які, як правило, гірше продуктивності):

//i

\S matches anything except space character and [^)] matches anything except ) characters (it's a negated character class). In fact, you might want to exclude ( from the \S as well, because otherwise it could already match into the parentheses:

//i

If the note part has to contain at least one character you should make that clear in the regex as well, by using + instead of *

//i

Якщо, з іншого боку, частина note є необов'язковою, для моєї попередньої версії потрібно щонайменше 2 пробілів (через два + + ). У такому випадку можна згрупувати частину note разом з наступним простором і зробити її необов'язковою разом. Таким чином, вам знадобиться тільки пробіл, якщо note є. Щоб припинити зйомку (щоб ви не отримали ще два рядки), використовуйте (?: ...) для групування замість (...) :

//i

Зверніть увагу, що матч все одно дасть вам масив, що містить рядок, який ви шукаєте (і ви нічого не можете зробити з цього приводу), тому вам доведеться мати доступ до нього за допомогою [0] .

0
додано
@ user1360809 так, я неправильно зрозумів цю частину вашого питання і відредагував свою відповідь зараз.
додано Автор Martin Ender, джерело
може підтвердити, що він працює! ;) Незважаючи на те, що синтаксис трохи складніший, я віддаю перевагу цій відповіді зараз ...
додано Автор user1360809, джерело
спасибі - вона як і раніше, здається, збігається з пробілами - будь-яка ідея чому?
додано Автор user1360809, джерело
ІТ КПІ - JavaScript
ІТ КПІ - JavaScript
504 учасників

співтовариство javascript розробників в Telegram