Ответ Коби частично работает, но не соответствует строкам кода, в которых нет комментария в конце.
Он также потерпит неудачу, когда встретится с интерполяцией строк, например ::10000
str = "My name is #{first_name} #{last_name}" # first comment
... будет ошибочно сопоставлено как: str = "My name is #{first_name}
Вам нужно более полное регулярное выражение. Вот одна идея:
/^[\t ]*([^#"'\r\n]("(\\"|[^"])*"|'(\\'|[^'])*'|[^#\n\r])*)(#([^#\r\n]*))?/
^[\t ]*
- ведущие пробелы.
([^#"'\r\n]("(\\"|[^"])*"|'(\\'|[^'])*'|[^#\n\r])*)
- соответствует строке кода.
Разбивка:
[^#"'\r\n]
- первый символ в строке кода, и ...
"(\\"|[^"])*"
- строка в двойных кавычках или ...
'(\\'|[^'])*'
- строка в одинарных кавычках или ...
[^#\n\r]
- любой другой символ вне строки в кавычках, который не является #
или окончанием строки.
(#([^#\r\n]*))?
- Соответствует первому комментарию в конце строки кода, если есть.
Из-за более сложной логики это будет захватывать 6 подшаблонов для каждого совпадения. Подшаблон 1 - это код, подшаблон 6 - комментарий, остальные можно игнорировать.
С учетом следующего блока кода:
# Some ignored comment.
1 + 1 # Simple math (this comment would be collected) # ignored
# ignored
user = User.new
user.name = "Ryan #{last_name}" # Setting an attribute # Another ignored comment
Приведенное выше регулярное выражение выдает следующее (для краткости я исключил подшаблоны 2, 3, 4, 5):
1. 1 + 1
6. Simple math (this comment would be collected)
1. user = User.new
6.
1. user.name = "Ryan #{last_name}"
6. Setting an attribute
Демо: http://rubular.com/r/yKxEazjNPC