Сделать манипуляции со строками более удобными в Mathematica - PullRequest
3 голосов
/ 17 апреля 2011

С Mathematica я всегда чувствую, что строки - это «граждане второго сорта». По сравнению с таким языком, как PERL, для выполнения одной и той же задачи нужно жонглировать большим количеством кода.

Доступный функционал неплохой, но синтаксис неудобный. В то время как есть несколько сокращенных форм, таких как <> для StringJoin и ~~ для StringExpression, большая часть функциональности строк не имеет такого синтаксиса и использует неуклюжие имена, такие как: StringReplace, StringDrop, StringReverse, Characters, CharacterRange, FromCharacterCode и RegularExpression.

В Mathematica строки обрабатываются как математические объекты, позволяя 5 "a" + "b", где "a" и "b" выступать в качестве символов. Это функция, которую я бы не изменил, даже если бы это не нарушало стеки кода. Тем не менее он исключает определенный краткий строковый синтаксис, в котором выражение 5 "a" + "b" будет отображено, например, "aaaaab".


Какой лучший способ сделать манипуляции со строками более удобным в Mathematica?

Идеи, которые приходят на ум, в одиночку или в комбинации:

  1. Перегрузка существующих функций для работы со строками, например, Take, Replace, Reverse.

    • Это была первоначальная тема моего вопроса, на которую Саша ответил. Это было сочтено нецелесообразным.

  2. Используйте сокращенные имена для строковых функций, например, StringReplace >> StrRpl, Characters >> Chrs, RegularExpression >> "RegEx"

  3. Создание нового инфиксного синтаксиса для строковых функций и, возможно, новых строковых операций.

  4. Создать новый контейнер для строк, например, str["string"], а затем определения для различных функций. (Это было предложено Леонидом Шифриным.)

  5. Переменная (4), расширяет строки (автоматически?) До символов, например, "string" >> str["s","t","r","i","n","g"], чтобы символы были видны Part, Take и т. Д.

  6. Вызовите другой язык, например, PERL, из Mathematica для обработки строк.

  7. Создание новых строковых функций, которые объединяют часто используемые последовательности операций.

1 Ответ

5 голосов
/ 17 апреля 2011

Я думаю, причина того, что эти операции имеют имена String *, заключается в том, что они имеют крошечные различия по сравнению со своими аналогами в списке. В частности, сравнить Cases с StringCases.

Теперь способ достичь того, чего вы хотите, это сделать так:

Begin["StringOverload`"];
{Drop, Cases, Take, Reverse};
Unprotect[String];
ToStringHead[Drop] = StringDrop;
ToStringHead[Take] = StringTake;
ToStringHead[Cases] = StringCases;
ToStringHead[Reverse] = StringReverse;
String /: 
 HoldPattern[(h : Drop | Cases | Take | Reverse)[s_String, rest__]] :=
  With[{head = ToStringHead[h]}, head[s, rest]]
RemoveOverloading[] := 
 UpValues[String] = 
  DeleteCases[UpValues[String], 
   x_ /; ! FreeQ[Unevaluated[x], (Drop | Cases | Take | Reverse)]]
End[];

Вы можете загрузить вещи с помощью Get или Need, а снять перегрузку с помощью RemoveOverloading[], вызываемой в правильном контексте.

In[21]:= Cases["this is a sentence", RegularExpression["\\s\\w\\w\\s"]]

Out[21]= {" is "}

In[22]:= Take["This is dangerous", -9]

Out[22]= "dangerous"

In[23]:= Drop["This is dangerous", -9]

Out[23]= "This is "

Хотя я не думаю, что это правильный путь. Вы можете рассмотреть возможность введения более коротких символов в некотором контексте, который автоматически оценивается как String* символов

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...