Я хочу переформатировать свою документацию Swift с

/**
  Lorem Ipsum is simply dummy text of the printing and typesetting industry. 
  Lorem Ipsum has been the industry's standard dummy text ever since the 
  1500s, when an unknown printer took a galley of type and scrambled it to 
  make a type specimen book. It has survived not only five centuries, but 
  also the leap into electronic typesetting, remaining essentially 
  unchanged. It was popularised in the 1960s with the release of Letraset 
  sheets containing Lorem Ipsum passages, and more recently with desktop 
  publishing software like Aldus PageMaker including versions of Lorem Ipsum.
  */

К

/// Lorem Ipsum is simply dummy text of the printing and typesetting industry. 
/// Lorem Ipsum has been the industry's standard dummy text ever since the 
/// 1500s, when an unknown printer took a galley of type and scrambled it to 
/// make a type specimen book. It has survived not only five centuries, but 
/// also the leap into electronic typesetting, remaining essentially 
/// unchanged. It was popularised in the 1960s with the release of Letraset 
/// sheets containing Lorem Ipsum passages, and more recently with desktop 
/// publishing software like Aldus PageMaker including versions of Lorem Ipsum.

Поиск и замена регулярного выражения edit: с использованием механизма поиска / замены регулярных выражений Xcode будет предпочтительнее, потому что одному Богу известно, сколько заметок в моей библиотеке из более чем 200 различных классов. Выражение для поиска этих блоков простое, но я не знаю, как сделать свое выражение замены, чтобы я мог добавить префикс к каждой строке.

Текущее поисковое выражение: (?s:/\*\*(.*?)\*/) - соответствует всему тексту между /** */

Текущее выражение замены : /// $1

Очевидно, что приведенные выше выражения не достигают того, что я ищу. Я заранее ценю любую помощь! Спасибо.

3
NoodleOfDeath 8 Сен 2016 в 18:48

2 ответа

Лучший ответ

Это лучшее решение, которое я мог придумать, но оно зависит от некоторых специализированных якорей PCRE (наиболее важно \G, но я также выбрал \A и \K), поэтому оно может не работать в вашем аромате регулярного выражения. Это также двухэтапное решение, но я не думаю, что можно было бы свести его к одному - хотелось бы, чтобы кто-то доказал, что я ошибаюсь!


Во-первых, вы хотите сопоставить каждую строку, начинающуюся с пробела между /** и */, и заменить пробел на ///.

Найти :

~(?<=/[*]{2}|(?<!\A)\G)\n\K^\s*+(?![*]/)(.*)$~gm

Заменить :

/// $1

Демо.


Затем мы хотим взять результат этой замены и удалить оставшиеся строки, обозначающие старый комментарий, /** и */.

Найти :

~^.*(?:/[*]{2}|[*]/).*$\n?~gm

Заменить :

[null]

Демо.


Большая часть вышеперечисленного проста или, по крайней мере, должна предполагать, что у вас есть базовое понимание регулярных выражений ... что, похоже, у вас есть. Самым очевидным из них является первый. Давайте разберемся (ура!) ...

(?<=       # start a zero-length lookahead
  /[*]{2}  # look for the start of a comment
 |         # or...
  (?<!\A)  # negate this part if we're at the beginning of the string
  \G       # start at the end of the last match (or beginning of string)
)          # end that lookahead and move on to each line
\n\K       # find the newline and then reset the match for clarity
^\s*+      # match whitespace at the beginning of the line
(?![*]/)   # negate this match if we're at the end of the comment
(.*)$      # capture everything up until the end of the line

Единственное, что из вышеперечисленного может потребовать дополнительных пояснений, - это (?<!\A)\G) "хак", который я использую. \G позволяет нам начать совпадение в конце последнего совпадения, что совершенно необходимо (для такого всеобъемлющего решения, как это) в повторяющейся задаче, как здесь. Однако \G также соответствует началу строки, которая нам не нужна (мы имеем дело с этим в первой половине просмотра вперед, где мы сопоставляем начало комментария), поэтому мы отменяем сопоставление начала строки. с (?<!\A). Бум!

\K не является обязательным, но делает выражение более чистым, когда мы усложняем его. Без него \n является частью совпадения, и нам пришлось бы вручную заменить его на \n\\\ $1.

2
Sam 8 Сен 2016 в 16:30

Несмотря на великолепную работу с выражениями в ответе Сэма, я в итоге применил следующий уродливый метод грубой силы, на случай, если кому-то интересно:

Шаг 1

Найти: /\*\*\n
Заменить: "" - ничего

Шаг 2

Найти: ^\s*-\s*(?=parameter|returns|note|important|precondition|postcondition)
Заменить: ///

Шаг 3 Найти: (?<=/// .{0,80}?\n)(\s*)(?!(\s*(case|let|convenience|enum|struct|init|required|override|weak|public|private|static|class|var|func|lazy|@|///))) Заменить: $1///

Шаг 4 Найти: ^\s*\*/\n(?=case|let|convenience|enum|struct|init|required|override|weak|public|private|static|class|var|func|lazy)
Заменить: "" - ничего

0
Community 23 Май 2017 в 11:51