Ruby 1.9.1, OSX 10.5.8
Я пытаюсь написать простое приложение, которое анализирует кучу файлов шаблонов HTML на основе Java, чтобы заменить точку (.) Подчеркиванием, если оно содержится в определенном теге. Я все время использую ruby для этих типов служебных приложений, и думал, что было бы не проблема собрать что-нибудь с помощью поддержки регулярных выражений ruby. Итак, я создаю объект Regexp.new ..., открываю файл, читаю его построчно, затем сопоставляю каждую строку с шаблоном. Если я получаю совпадение, я создаю новую строку, используя replaceString = currentMatch.gsub ( /./, '_'), затем создайте еще одну замену как целую строку с помощью newReplaceRegex = Regexp.escape (currentMatch) и, наконец, замените обратно в текущую строку с помощью line.gsub (newReplaceRegex, replaceString). ...
Проблема, с которой я столкнулся, заключается в том, что при доступе к индексам в возвращенном объекте MatchData я получаю первый результат дважды, и в нем отсутствует вторая подстрока, которую в противном случае она должна находить. Более странно то, что при тестировании того же шаблона и того же тестового текста с использованием rubular.com, он работает, как ожидалось. Смотрите результаты здесь
Мой рисунок:
(<(?: WEBOBJECT | webobject) (?: NAME | name) = (?: [A-zA-Z0-9] +.) + (?: [A-zA-Z0-9] +) (?>))
Текстовый текст:
<WEBOBJECT NAME=admin.normalMode.someOtherPatternWeDontWant.moreThatWeDontWant>moreNonMatchingText<WEBOBJECT NAME=admin.SecondLineMatch>AndEvenMoreNonMatchingText
Вот соответствующий код:
tagRegex = Regexp.new('(<(?:WEBOBJECT|webobject) (?:NAME|name)=(?:[a-zA-Z0-9]+\.)+(?:[a-zA-Z0-9]+)(?:>))+')
testFile = File.open ('RegexTestingCompFix.txt', "r +")
LineCount = 0
testFile.each {| htmlLine |
lineCount + = 1
ставит («Текущая строка: # {htmlLine} в номер строки: # {lineCount}»)
tagMatch = tagRegex.match (htmlLine)
if (tagMatch)
matchesArray = tagMatch.to_a
firstMatch = matchesArray[0]
secondMatch = matchesArray[1]
puts "First match: #{firstMatch} and second match #{secondMatch}"
tagMatch.captures.each {|lineMatchCapture|
puts "Current capture for tagMatches: #{lineMatchCapture} of total match count #{matchesArray.size}"
#create a new regex using the match results; make sure to use auto escape method
originalPatternString = Regexp.escape(lineMatchCapture)
replacementRegex = Regexp.new(originalPatternString)
#replace any periods with underscores in a copy of lineMatchCapture
periodToUnderscoreCorrection = lineMatchCapture.gsub(/\./, '_')
#replace original match with underscore replaced copy within line
htmlLine.gsub!(replacementRegex, periodToUnderscoreCorrection)
puts "The modified htmlLine is now: #{htmlLine}"
}
end
}
Я бы подумал, что должен получить первый тег в matchData [0], а затем второй тег в matchData 1 , или, что я на самом деле делаю, потому что я не знаю, сколько совпадений я попадем в любую данную строку - matchData.to_a.each. И в этом случае matchData имеет два захвата, но они оба являются первым тегом match
which is: <WEBOBJECT NAME=admin.normalMode.someOtherPatternWeDontWant.moreThatWeDontWant>
Итак, какого чёрта я делаю неправильно, почему рубулярный тест дает мне ожидаемые результаты?